6

I just found that leafletjs and openlayers have two different conventions to convert coordinates from EPSG:4326 (WGS 84) to tile names ({Z}/{X}/{Y}).

Thus I would like to have more information about the origin and usages of such two standards, and I would also know if there is a generalized way to implement the conversions from any projection (using only proj4 data) to tiles names.

I added the following preliminary snippet to mod_tile, so that it can serve EPSG:4326 (WGS 84) tiles:

} else if (strcmp(srs, "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs") == 0) {
    syslog(LOG_DEBUG, "Using wgs84 projection settings");
    prj = (struct projectionconfig *)malloc(sizeof(struct projectionconfig));
    prj->bound_x0 = -180;
    prj->bound_x1 =  180;
    prj->bound_y0 = -90;
    prj->bound_y1 =  90;
    prj->aspect_x = 2;
    prj->aspect_y = 1;

To display a tiled map I use:

Leafletjs

L.tileLayer('.../base/{z}/{x}/{y}.png');`

Openlayers

('.../base/{z}/{x}/{y}.png').replace('{z}', (tileCoord[0] - 1).toString())
                            .replace('{x}', tileCoord[1].toString())
                            .replace('{y}', (-tileCoord[2] - 1).toString());

The results with the two libraries is exactly the same, if I adapt the zoom level.

EDIT: My target is to provide a generalized patch for mod_tile (and ev. other services), but from the answer below, I think I need to provide extra parameters in a configuration file of mod_tile (e.g. renderd.conf) to generate the correct tile with the expected name.

3

2 Answers 2

4

There is a good explanation at the OSM wiki. It boils down to projecting EPSG:4326 coordinates to EPSG:3857 and working the X and Y coordinates of the tile from the X and Y coordinates in that CRS.

The "generalized" way to provide tiles for any CRS is TMS.

3
  • I'm asking about tile names in EPSG:4326. Leafletjs uses Google Maps style [so also OSM style] (top to bottom in {Y}, zoom zero is one tile). Your links about TMS explain the other standard (bottom to top in {Y}). I still need to find what service (in TMS style) uses the origin and zoom level as expected in Openlayers. Commented Feb 12, 2016 at 8:57
  • There is no suck thing as "the tile grid that OpenLayers expects" - OL3 has superb support for tile URL schemes, and user-defined tile grids. If you need to serve EPSG:4326 in a tiled fashion, I heartily recommend you set up a TMS server for them. Commented Feb 12, 2016 at 9:05
  • I mean a sort of default. OL3 chooses, for XYZ, a default way to construct tile urls. My code (copied from OL3 examples) mangle urls with XYZ.tileUrlFunction so that I view the same tile in the same way as leafletjs (using the the default tile names). So, what should be the default rendering in mod_tile, on maps with EPSG:4326 projection? The question is about what are the reasons behind the two different defaults, not how to view tiles with the other default. Commented Feb 12, 2016 at 9:20
0

It would be helpful to you. In google maps API.

code is in link below.

  var tile = new google.maps.Point();
  var point = new google.maps.Point();
  var zoom = map.getZoom();

  var proj = map.getProjection();

  point = proj.fromLatLngToPoint(latLng);

  tile.x = Math.floor( (point.x / 256.0) * Math.pow(2, zoom));
  tile.y = Math.floor( (point.y / 256.0) * Math.pow(2, zoom));

  if (tile.x < 0 || tile.y < 0) return;
  if (tile.x >= (1 << zoom) || tile.y >= (1 << zoom)) return;

  var boundspixels = tile.x*256 + " " + tile.y*256 + " " + (tile.x+1)*256 + " " + (tile.y+1)*256;

  latLng1 = proj.fromPointToLatLng(new google.maps.Point(tile.x*256/ Math.pow(2, zoom),(tile.y+1)*256/ Math.pow(2, zoom)));
  latLng2 = proj.fromPointToLatLng(new google.maps.Point((tile.x+1)*256/ Math.pow(2, zoom),tile.y*256/ Math.pow(2, zoom)));
  var boundswgs84 = latLng1.lng()+" "+latLng1.lat()+"<br/>"+latLng2.lng()+" "+latLng2.lat();

  latLng = proj.fromPointToLatLng(new google.maps.Point(((tile.x+1)*256-128) / Math.pow(2, zoom),(tile.y*256+100) / Math.pow(2, zoom)));

  initialResolution = 2 * Math.PI * 6378137 / 256;  // == 156543.0339
  originShift = 2 * Math.PI * 6378137 / 2.0; // == 20037508.34
  res = initialResolution / Math.pow(2, zoom);
  tile.y = ((1 << zoom) - tile.y - 1); // TMS
  var boundsmercator =  (tile.x*256 * res - originShift) + " " + (tile.y*256 * res - originShift) +
  "<br/>" + ((tile.x+1)*256 * res - originShift) + " " + ((tile.y+1)*256 * res - originShift);

maptiler

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.