Proj4Leaflet not working with various tile servers - leaflet

I followed the introduction on the home page of Proj4Leaflet to create a basic slippy-map with their example projection (code below). This is working without issue, but is using the tile servers of the company that maintains Proj4Leafet, specifically: http://api.geosition.com/tile/osm-bright-3006/{z}/{x}/{y}.png
When I try to use an alternative tile server, such as Mapbox's https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken} (where I use my own token), CartoDB's http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png or OSM's http://a.tile.openstreetmap.org/{z}/{x}/{y}.png the map simply doesn't render and I get a blank grey map.
Is it possible to use other tile servers with Proj4Leaflet, or is there something in my configuration that is incompatible with them?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Leaflet GeoJSON</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="map"></div>
<script src="js/require.js"></script>
<script>
requirejs.config({
baseUrl: 'js',
paths: {
"leaflet": "http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet"
}
});
requirejs(['leaflet', 'proj4', 'proj4leaflet'],
function (L, proj4, proj4leaflet) {
// SWEREF99 TM (EPSG:3006) with map's pixel origin at SWEREF99 TM coordinate (0, 0)
var crs = new L.Proj.CRS(
'EPSG:3006',
'+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs',
{
resolutions: [8192, 4096, 2048, 1024, 512, 256, 128,
64, 32, 16, 8, 4, 2, 1, 0.5],
origin: [0, 0]
});
var map = new L.map('map',
{
center: [59.35, 18.066667],
zoom: 10,
maxZoom: 14,
minZoom: 0,
crs: crs
});
L.tileLayer('http://api.geosition.com/tile/osm-bright-3006/{z}/{x}/{y}.png', {
maxZoom: crs.options.resolutions.length,
minZoom: 0,
continuousWorld: true,
attribution: 'Map data © OpenStreetMap contributors, Imagery © 2013 Kartena'
}).addTo(map);
});
</script>
</body>
</html>

Proj4Leaflet is a Leaflet plugin meant for when you need to use a Coordinate Reference System (CRS) that's not supported by Leaflet out of the box. Almost every tileprovider out there uses EPSG3857 which is Leaflet's default CRS:
The most common CRS for online maps, used by almost all free and commercial tile providers. Uses Spherical Mercator projection. Set in by default in Map's crs option.
Mapbox, CartoDB and OSM all serve EPSG3857 tilesets. From the Mapbox's help page:
Mapbox supports the popular Web Mercator projection, and currently does not support any other projections as output. Web Mercator is a nearly conformal projection that is adopted by the vast majority of web maps and its use allows you to combine Mapbox’s maps with other layers in the same projection. Commonly this projection is referred to as EPSG:900913 or EPSG:3857.
https://www.mapbox.com/help/projection-support/
Without looking i'm betting you'll find the same answer over at CartoDB and OSM. If you need to use EPSG3006 you'll need to stick with providers that serve tiles in that projection. Here's one: http://maps.omniscale.com/en/openstreetmap/epsg-3006

Mapbox will only serve tiles in Web Mercator (EPSG:3857). To use proj4Leaflet with tiled data you need tiles which are already projected (for example NASA provides tiled maps in stereographic projections for the poles). You will either need to find or establish a tile server which is set to output in your desired projection (EPSG:3006).
proj4 will however convert vector data such as geojson on the fly.

Related

How to add municipalities to map?

I've successfully implemented a map of Denmark using Leaflet. However, I need to show the municipalities in Denmark, and this is surprisingly complicated.
On this page, I gather that there are Mapbox Tileset IDs for administrative boundaries, so I suppose in principle, I could use these tilesets, but I feel this is not adequately explained on this page.
Can tilesets be added to a Leaflet map as a layer? This is unclear. My code for the basic map looks like this:
var map = L.map('map').setView([56,12], 7);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, Imagery © Mapbox',
maxZoom: 20,
id: 'mapbox/light-v9',
tileSize: 512,
zoomOffset: -1,
accessToken: '[my_access_token]'
}).addTo(map);
Just replacing mapbox/light-v9 with e.g. mapbox/boundaries-adm4-v3 and the map is gone. Adding an entire new L.tilelayer(...id('mapbox/boundaries-adm4-v3')...).addTo(map); gives me the same old map with no administrative boundaries.
Am I naïve in expecting Mapbox to provide me with a free map of the municipalities of Denmark?
Have I combined too many things by using Leaflet, Mapbox and OpenStreetMaps?
How do I accomplish what I need? 1. Drawing of the Danish municipality boundaries on the map; 2. Coloring of selected municipalities.
Note that these are Vector Tiles.
Leaflet has no built-in functionality for rendering these types of tiles. However, you can take a look at the officially documented Vector-Tiles plugins: https://leafletjs.com/plugins.html#vector-tiles

mbtiles files with leaflet

I am using Tileserver to host my mbtiles file. I am trying to open my mbtile sfile using leaflet in ionic. I am not able to see map. Following is the code that I am using:
leaflet.tileLayer('http://subdomain/styles/klokantech-basic/?vector#{z}/{x}/{y}').addTo(map);
I have also tried to use:
var mb = leaflet.tileLayer.mbTiles('http://subdomain/styles/klokantech-basic/?vector#{z}/{x}/{y}').addTo(this.map);
But I am just able to see grey screen on my device instead of map.
It sounds like leaflet is loading the tiles from your tile server, but the map you are serving doesn't have data for the location and zoom level you are looking at. Try this script.
Leaflet example:
<script>
var map = L.map('map').
setView([lat, lon], zoom );
//OpenMapTiles
L.tileLayer('http://subdomain/styles/klokantech-basic/{z}/{x}/{y}.png', {
//tms: true,
maxZoom: 20,
attribution: 'Map data © OpenStreetMap'
}).addTo(map);
</script>
An alternative is to use Mapbox GL JS, this pushes the rendering to your browser and allows you to use tileserver-gl-light as well:
<script src='http://subdomain/mapbox-gl.js'></script>
<link href='http://subdomain/mapbox-gl.css' rel='stylesheet' />
Mapbox GL JS
var map = new mapboxgl.Map({
container: 'map',
style: 'http://subdomain/styles/klokantech-basic/style.json',
center: [lon, lat],
zoom: 7
});
When creating the mbtiles file, make sure you create it to support the zoom level and location you set, OpenMapTiles defaults to a zoom level of 7, it may needs to be increased for your map, I use 14, which supports a zoom level to 20 for rendering.

Leaflet offset PNG tile layer coordinates

I am trying to combine several hand-drawn map images into an interactive HTML feature using leaflet.
I've been trying to work up from the most basic code. To begin with I added three pictures at different zoom levels. I am still experimenting with that, but here's what the code looks like now:
var map = L.map('map').setView([0, 0], 10);
L.tileLayer('Drawn/Pacific.png',
{tileSize: 800, noWrap: true, minZoom:10, maxZoom: 10}).addTo(map);
L.tileLayer('Drawn/Hong Kong.png',
{tileSize: 800, noWrap: true, minZoom: 11, maxZoom: 11}).addTo(map);
L.tileLayer('Drawn/Kowloon.png',
{tileSize: 800, noWrap: true, minZoom: 12, maxZoom: 12}).addTo(map);
How can I offset the starting coordinates of these layers so that they line (So that Hong Kong at zoom level 11 is actually where it should be in the Pacific Tile at zoom level 10)?
Thanks!
It looks like you have only 1 big image per "tile layer", so you would probably be interested in implementing your features as Image Overlays instead:
Used to load and display a single image over specific bounds of the map.
With Image Overlay, you can specify the geographical coordinates of your image, so that it is placed exactly where you want. You can adjust the relative coordinates of your 3 images, so that they line up as you need.

Leaflet GeoJson

Can someone explain me why this leaflet code works for visualizing the GeoJson data of the state New York but I can't draw the data of the city new york. I used the same export preferences for the files in QGIS.
I used the data from the following links:
New York city
http://www.nyc.gov/html/dcp/html/bytes/districts_download_metadata.shtml
New York state
http://cugir.mannlib.cornell.edu/bucketinfo.jsp?id=7865
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<link rel="stylesheet" href="style_blank.css" />
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="sdfgsdgdfgfdsgd.js"></script>
<div id="map"></div>
<script>
var map = L.map('map',{
center: [5,28],
zoom: 3,
minZoom: 2,
maxZoom: 18
});
L.geoJson(data, {
style: function (feature) {
return {color: feature.properties.color};
},
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.description);
}
}).addTo(map);
</script>
</body>
</html>
From the lack of specificity of the question, it's difficult to say where the problem lies. However, I have a good guess.
I followed your link to the city data and downloaded the "Borough Boundaries" shapefile, then imported it into QGIS. The coordinate units appear to be either feet or meters, indicating that it is projected data. Leaflet can't deal with projected coordinates; it requires unprojected lat/long (decimal degree) coordinates. What you need to do is follow these steps:
1) Find out what projection the data is in;
2) Assign that projection to the data using GIS software (such as free, open-source QGIS);
3) Reproject the data into the WGS 84 (EPSG:4326) coordinate reference system;
4) Save the reprojected data as a new GeoJSON.
Try putting the city data in a gist
Github will display the data on a basemap, and you will be able to see if the data are
not displaying (likely problem with the geojson)
displaying, but in the wrong place (likely projection issue)
displaying in the right place (likely problem in your code)
You will need to import a tile first, several are paid but with little research you can find plenty of freebies.

Labelled satellite base map layer (not using Google Maps)

I am having trouble recreating in Leaflet something that I found possible using the Google Maps API, which is having the base layer of my web map being geographically labeled satellite imagery. I can find "Street View" base imagery and I can find satellite imagery, but not with them combined into one base map layer.
Can anyone point me to an free resource for this kind of base map to use with Leaflet?
If what I am looking for does not exist, could my problem be solved by overlaying an existing "street view" map tile layer over the non-labelled satellite map tile layer?
Mapbox.com offers a basemap called "satellite streets". It looks like this.
You can sign up for free and include it into your leaflet map using your Map ID:
L.tileLayer('http://{s}.tiles.mapbox.com/v3/MapID/{z}/{x}/{y}.png', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18
}).addTo(map);