How to draw map layer only inside FeatureGroup elements in Leaflet? - leaflet

For example, I have two map layers: open street maps and our own one. Both can be defined this way:
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap'
}).addTo(mapObject);
The question is in that I do not need to draw the second layer on a whole map, but only inside elements of L.FeatureGroup:
var drawnItems = new L.FeatureGroup().addTo(mapObject);
Especially inside polygons, rectangles, etc... Is that possible with leaflet? If yes, how this can be achieved?
Thanks.

One approach would be to use the bounds option of your L.TileLayer, i.e.:
var drawnItems = new L.FeatureGroup( .... );
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: ...,
bounds: drawnItems.getBounds()
}).addTo(mapObject);
Another approach would be to look at the list of plugins for tile display, and use either TileLayer.BoundaryCanvas or leaflet-tilelayer-mask (keep in mind that more plugins might be applicable, and more plugins might appear in the future).

Related

How to change projection for L.imageOverlay in leaflet [duplicate]

I have implemented the following piece of code where I need to fit a layer over a map, that I made using QGIS. But the coordinates are not working correctly, what should I do? The problem are the wrong coordinates or there is a way to fit the layer in the map correctly using overlay?
var L;
var initialCoordinates = [-14.91, -43.20];
var initialZoomLevel = 4;
// create a map in the "map" div, set the view to a given place and zoom
map = L.map('heatmap').setView(initialCoordinates, initialZoomLevel);
L.map('map', {
crs: L.CRS.EPSG4326
});
// add an OpenStreetMap tile layer
// L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}{r}.png', {
// attribution: '© OpenStreetMap © CartoDB',
// maxZoom: 19
// }).addTo(map);
L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}{r}.{ext}', {
attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap',
subdomains: 'abcd',
minZoom: 0,
maxZoom: 18,
ext: 'png'
}).addTo(map);
// [[5.32, -28.95], [-33.1999, -73.9]]
var imageUrl = '/images/temperatureMapDefault.png', //temperatureMapDefault.png
imageBounds = [[5.32, -28.95], [-33.1999, -73.9]]; // [[ymin, xmin][ymax, xmax]]
L.imageOverlay(imageUrl, imageBounds).addTo(map);
The coordinates for the bounding box are working just fine; the problem is in the projections.
Your QGIS project, and your output image, are using EPSG:4326. Leaflet uses EPSG:3857 (spherical mercator) for display. If you try to overlay a stretched EPSG:4326 image over a EPSG:3957 one, the top and bottom edges will fit but you'll experience a vertical shift.
You can see this more clearly by creating a bigger image in EPSG:4326 with country boundaries. I encourage you to experiment.
Please read https://docs.qgis.org/2.18/en/docs/user_manual/working_with_projections/working_with_projections.html and related documentation in order to configure your QGIS project to use a different CRS.

How to fit layer correctly in map using leaflet overlay?

I have implemented the following piece of code where I need to fit a layer over a map, that I made using QGIS. But the coordinates are not working correctly, what should I do? The problem are the wrong coordinates or there is a way to fit the layer in the map correctly using overlay?
var L;
var initialCoordinates = [-14.91, -43.20];
var initialZoomLevel = 4;
// create a map in the "map" div, set the view to a given place and zoom
map = L.map('heatmap').setView(initialCoordinates, initialZoomLevel);
L.map('map', {
crs: L.CRS.EPSG4326
});
// add an OpenStreetMap tile layer
// L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}{r}.png', {
// attribution: '© OpenStreetMap © CartoDB',
// maxZoom: 19
// }).addTo(map);
L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}{r}.{ext}', {
attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap',
subdomains: 'abcd',
minZoom: 0,
maxZoom: 18,
ext: 'png'
}).addTo(map);
// [[5.32, -28.95], [-33.1999, -73.9]]
var imageUrl = '/images/temperatureMapDefault.png', //temperatureMapDefault.png
imageBounds = [[5.32, -28.95], [-33.1999, -73.9]]; // [[ymin, xmin][ymax, xmax]]
L.imageOverlay(imageUrl, imageBounds).addTo(map);
The coordinates for the bounding box are working just fine; the problem is in the projections.
Your QGIS project, and your output image, are using EPSG:4326. Leaflet uses EPSG:3857 (spherical mercator) for display. If you try to overlay a stretched EPSG:4326 image over a EPSG:3957 one, the top and bottom edges will fit but you'll experience a vertical shift.
You can see this more clearly by creating a bigger image in EPSG:4326 with country boundaries. I encourage you to experiment.
Please read https://docs.qgis.org/2.18/en/docs/user_manual/working_with_projections/working_with_projections.html and related documentation in order to configure your QGIS project to use a different CRS.

Leafletjs show a single wrapped map

I want to show a single world map and wrap it around so that each area is shown only once on the screen. Please refer the fiddle http://jsfiddle.net/8m13d6vs/
var osmUrl = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
osm = L.tileLayer(osmUrl, {
noWrap: false,
attribution: "<a href='http://openstreetmap.org'>OpenStreetMap</a>"
});
var map = L.map('map').setView([0, 0], 1).addLayer(osm);
In the above fiddle, wrap is on, but the world map is duplicated. I want a single world map, and on left/right mouse drag, it should wrap around. It should be responsive to the area as well. Is there any way to achieve this? Hope my problem statement is understandable.
There's the Leaflet worldCopyJump option:
var map = L.map('map', {worldCopyJump: true}).setView([0, 0], 1).addLayer(osm);
It defaults to false, but setting this to true will copy the contents of the map over as the user pans beyond the map boundaries.
This sounds like a misunderstanding of the definition of "wrap":
In the context of Leaflet's Tile Layer / Grid Layer option noWrap, it says:
Whether the layer is wrapped around the antimeridian. If true, the GridLayer will only be displayed once at low zoom levels.
So it sounds like simply noWrap: true should achieve your objective.
Updated JSFiddle: http://jsfiddle.net/8m13d6vs/3/
BTW you should consider upgrading Leaflet version to 1+

How to toggle initial layer visibility in leaflet.js

I've created a map in leaflet.js with multiple layers but can't work out how to toggle one layer to initially appear on the map.
Here is the link
I'm sure it's fairly straightforward but just can't figure it out.
After declaring your layers you need to add one to the map, just like you did with your tilelayer. See the code below. That should work. The layercontrol will work out that the layer is visible/added to the map and check it in the list.
var map = L.map('map').setView([52.814172, -2.079479], 9);
L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg', {
maxZoom: 18,
attribution: 'Map tiles by Stamen Design, under CC BY 3.0. Data by OpenStreetMap, under CC BY SA.'
}).addTo(map);
// Left out layer-declarations, they are HUGE
anti_soc.addTo(map); // here it is
var overlayMaps = {
"Anti-social behaviour" :anti_soc,
"Criminal damage and arson": crim_dam,
"Burglary": burg,
"Violence and sexual offences": viol,
"Other theft": other_theft,
"Vehicle crime": veh_crime,
"Shoplifting": shoplift,
"Public order": pub_ord,
"Robbery": robb,
"Bicycle theft": bikes,
"Drugs": drugs,
"Theft from the person": theft_person,
"Other crime": other_crime,
"Possession of weapons": weap
};
L.control.layers(null, overlayMaps).addTo(map);

Mapbox: How to continuously wrap a feature layer

Mapbox can continuously wrap tile layers such that you can scroll infinitely to the left and right over a repeating map of the world.
I have added a feature layer to a world map which displays some markers and, for some reason, this feature layer does not also wrap. The markers are only present on the original iteration of the world tiles layer.
I've tried using the noWrap: false options property that controls this characteristic on the tile layer when adding a feature layer, but it doesn't seem to have any effect.
Is there any way to do this?
Use the worldCopyJump option
example:
var map = L.mapbox.map('map', 'your.mapid', {center: [lat, long],
zoom: 4,
worldCopyJump: true
});
Not sure if I understand your question...
You can use
maxBounds: [[-90,-180],[90,180]]
for example
map = L.mapbox.map('map', '<some map id>',{minZoom: 0, maxZoom: 10, maxBounds: [[-90,-180],[90,180]]});
https://www.mapbox.com/mapbox.js/example/v1.0.0/maxbounds/