Showing more details ons leaflet map - javascript

Currently i'm implementing a leaflet map that serves map data from our own OSM server.
During the implementation I noticed that the details on the maps are not clearly visible. Street names are unclear and walking paths do not stand out.
We currently support a zoom level of 17. However, the tiles received are of high quality and show much more detail than leaflet does. If I zoom in further, the tiles unfortunately turn gray.
An implementation with OpenLayers looks clearer.
Is there a setting that solves this or that allows you to zoom in without showing gray tiles? I thought this was maxNativeZoom but if i put this field on 17, it still tries to show zoom level 18 tiles.
const osmLayer = new L.TileLayer(osmUrl,
{
attribution: '© OpenStreetMap contributors'
});
const element = elemId[0].className + "-" + mapId;
const map = new L.Map(element,
{
maxZoom: 22,
maxNativeZoom: 17,
minZoom: 9
});
map.addLayer(osmLayer);
return map;

I just moved the zoom settings to the tileLayer and that seems to work. The settings are properties of the tileLayer:
const osmLayer = new L.TileLayer(osmUrl,
{
maxZoom: 20,
maxNativeZoom: 17,
minZoom: 9,
attribution: '© OpenStreetMap contributors'
});
const element = elemId[0].className + "-" + mapId;
const map = new L.Map(element);
map.addLayer(osmLayer);
return map;

Related

Dealing with a huge GeoJson in leaflet

I'm currently dealing with a Huge GeoJson (about 100Mb) that contains all nation subdivisions in the world.
I want to display this GeoJson in a Leaflet map.
I have implemented this add-on that binds geojson-vt with leaflet.
However, simply I can't send 100Mb of data all the times...
This is a Javascript sample of the Leaflet implementation in JS:
//Map init
var map = L.map('map').setView([51.505, -0.09], 1);
//Tile layer
var tile_layer = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
//GeoJson fetch
world_geojson = fetch('./world.json').then(response => response.json()).then(
world_geojson => {
var options = {
maxZoom: 16,
tolerance: 3,
debug: 0,
style: {color:'#000',fillColor:"#0f0",weight: 1,opacity: 0.5,fillOpacity: 0.2}
};
//Actual geojson-vt layer implementation
var geojson_layer = L.geoJson.vt(world_geojson, options).addTo(map);
}
);
There is a way or some tricks to reduce the quantity of data sent to the users?
Thanks for support!

Make leaflet only display markers on start and endpoint whilst having multiple waypoints in route

Currently I initiate my Leaflet map in Angular like this:
private initMap(): void {
this.map = L.map('map', {
center: [ 51.4381919, 5.4797248 ],
zoom: 13
});
const tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
minZoom: 3,
attribution: '© OpenStreetMap'
});
tiles.addTo(this.map);
L.Routing.control({
waypoints: [
L.latLng(51.4508647, 5.4509124),
L.latLng(51.443867, 5.45591),
L.latLng(51.442804, 5.4648277)
],
}).addTo(this.map);
}
I have 3 waypoints, to calculate a route (this can go up to 1000's depending on how many datapoints I fetch from my database)
Currently Leaflet displays 3 markers, as I assigned it to do. But I want it to no matter the amount of waypoints I have, to draw a route but only display the first and last marker.
How would I do this?
You can use the createMarker function in Routing.plan:
var control = L.Routing.control({
plan: new L.Routing.Plan([
L.latLng(51.4508647, 5.4509124),
L.latLng(51.443867, 5.45591),
L.latLng(51.442804, 5.4648277)
],{
createMarker: function(i, waypoint, n){
if(i === 0 || i === n - 1){
// show markers
return L.marker(waypoint.latLng);
}
return false;
}
})
}).addTo(mymap);
https://jsfiddle.net/qhbjua2k/

Leaflet custom map with custom tiles

I am trying to make a custom map with leafletjs, and i've figured it out for the version 0.6.x but when it comes to the latest version (0.7.x) it does not work.
This is the code that works with 0.6.x
Anyone has had this issue before?
var mapMinZoom = 0;
var mapMaxZoom = 5;
var map = L.map('wu-map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom,
crs: L.CRS.Simple
}).setView([0, 0], mapMaxZoom);
var mapBounds = new L.LatLngBounds(
map.unproject([0, 3072], mapMaxZoom),
map.unproject([4352, 0], mapMaxZoom));
map.fitBounds(mapBounds);
L.tileLayer('images/map/{z}/{x}/{y}.png', {
minZoom: mapMinZoom, maxZoom: mapMaxZoom,
bounds: mapBounds,
attribution: 'Rendered with MapTiler',
noWrap: true,
tms: false
}).addTo(map);
There is a bug in leaflet.js 0.7 version that appears when crs option is set to L.CRS.Simple value (and not only). Leaflet 0.7 introduced L.CRS.getSize (a function which returns the size of the world in pixels for a particular zoom for particular coordinate reference system), which by default calls and returns the same value as L.CRS.scale. It works great for the default CRS and fails for others.
All I can suggest is to remove crs: L.CRS.Simple from your options object, it will be set to default value (L.CRS.EPSG3857):
var map = L.map('wu-map', {
maxZoom: mapMaxZoom,
minZoom: mapMinZoom
}).setView([0, 0], mapMaxZoom);

Leaflet OSM: Center mapview on polygon

I want generate a html file including Leaflet library to show an OpenStreetMap view with a polygon. The polygon on the map should be centered. To do so i followed this discussion, but its still unclear to me, how to center an arbitrary polygon and autozoom it. Autozoom means to me, that the polygon is completly in the visible map excerpt and fills it.
As example this would be the desired result:
This is my code so far:
var map;
var ajaxRequest;
var plotlist;
var plotlayers=[];
function initmap() {
// set up the map
map = new L.Map('map');
/* --- Replace for different URL for OSM tiles */
var url_base ='URL_TO_MY_OPENSTREETMAPS_SERVER';
var latitude = 50.2222;
var longtitude = 3.322343;
var poly = L.polygon([
[50.2222, 3.322343],
[50.2322, 3.323353],
[...]
]);
// create the tile layer with correct attribution
var osmUrl=url_base+'{z}/{x}/{y}.png';
var osmAttrib='Map data ɠOpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, {minZoom: 4, maxZoom: 20, attribution: osmAttrib});
// start the map at specific point
map.setView(new L.LatLng(latitude, longtitude),15);
map.addLayer(osm);
poly.addTo(map);
}
Especially it would be great, if there are "onboard" methods of Leaflet that i can use. How to calculate the center of a polygon is clear to (e.g. here) but maybe there are already implemnented methods i can use.
Solution:
// start the map at specific point
// map.setView(new L.LatLng(latitude, longtitude),15); <- Remove this line
map.addLayer(osm);
poly.addTo(map);
map.fitBounds(poly.getBounds()); // <- Add this line
Not exactly centering, but if you want the map to be fitted to the polygon:
map.fitBounds(poly.getBounds());
(doc).
To center more than one polygon is good to know that .fitBounds also accepts an array as argument, so you could do this:
const poly = [polygonA,polygonB,polygonC];
const bounds = poly.map(p=>p.getBounds());
mymap.fitBounds(bounds);

How to project pixel coordinates in leaflet?

I am trying to create a map based on an image which is 16384x16384 px, but I would also like to add markers at specific locations using pixel coordinates of this given image.
I created a tile layer, a map element and set maximum boundaries, so that I can't scroll out of the image, using this code:
var map = L.map('map', {
maxZoom: 6,
minZoom: 2,
crs: L.CRS.Simple
}).setView([0, 0], 2);
var southWest = map.unproject([0,16384], map.getMaxZoom());
var northEast = map.unproject([16384,0], map.getMaxZoom());
map.setMaxBounds(new L.LatLngBounds(southWest, northEast));
L.tileLayer('tiles/{z}/{x}/{y}.png', {
tms: true
}).addTo(map);
The points i'd like to add to the map are stored in an external file as GeoJSON, and they look like this http://www.de-egge.de/maps/terranigma/terraPoints.js
I load them using this snippet of code:
var terraPoints = new L.geoJson(points, {
onEachFeature: function (feature, layer) {
layer.bindPopup(
"<b>Ort: </b>" + feature.properties["points[, 1]"]
);
}
});
map.addLayer(terraPoints);
But of course, they don't show up, because the reference systems don't match. The points use pixel coordinates, but my map uses geographic coordinates.
Is there a way to "unproject" the points while loading them?
Any help is much appreciated and thanks in advance!
var geoJsonTest = new L.geoJson(geojsonFeature, {
coordsToLatLng: function (newcoords) {
return (map.unproject([newcoords[1], newcoords[0]], map.getMaxZoom()));
},
pointToLayer: function (feature, coords) {
return L.circleMarker(coords, geojsonMarkerOptions);
}
});
This is how you use in case you didn't figure it out yet. Seeing the coordinates are inverted I changed them around in the option. Works for perfectly for me.
L.GeoJSON has the coordsToLatLng() which should be useful for mapping the coordinates.
http://leafletjs.com/reference.html#geojson-coordstolatlng

Categories