stamen / modestmaps-js

Modest Maps javascript port
http://modestmaps.com
566 stars 152 forks source link

mbtiles in MM #49

Closed jhpoosthoek closed 13 years ago

jhpoosthoek commented 13 years ago

Hello,

I would like to get MBTILES (www.mbtiles.org) working in MM. I created such a file using gdal2tiles.py (https://github.com/developmentseed/gdal2mb). Next I created a PHP script (sqlite reading from https://github.com/mapbox/mbutil/) which reads the correct PNG file from the MBTILES file. It is called in javascript and MM through: var provider = new MM.TemplatedMapProvider('http://localhost/mb2xyz.php?code={Z}/{X}/{Y}');

This however doesn't work perfectly, the more you zoom in the less of the northern hemisphere is visible. I was wondering if people might recognize this problem as something from MM. If not, I guess it might be my PHP script. The MBTILES file seems to work perfectly when I open it using Maps on a Stick (http://developmentseed.org/blog/2010/oct/02/maps-stick-version-2-released)

A MBTILES example can be downloaded here: http://mapbox.com/#/tileset/natural-earth-2

Cheers, Jelmer


<?php $xyz = $_REQUEST['code']; $xyz = explode("/", $xyz); header("Content-Type: image/png"); $z = $xyz[0]; $x = $xyz[1]; $y = $xyz[2]; $y = pow(2, $z-1) - $y; $mbtiles_file = "natural-earth-2.mbtiles"; $db = new PDO('sqlite:'.$mbtiles_file);

$pngdata = @$db->prepare('select tile_data from tiles where zoom_level = '.$z.' and tile_column = '.$x.' and tile_row = '.$y.';'); $pngdata->execute(); $pngdata = $pngdata->fetchObject(); $pngdata = $pngdata->tile_data; echo $pngdata; ?>

shawnbot commented 13 years ago

I'm confused by the munging of the Y values (pow(2, $z-1) - $y): doesn't MBTiles use the same spherical mercator coordinate system as MM? Invalid Y values would certainly explain more of the vertical world disappearing as you zoom in.

RandomEtc commented 13 years ago

MBTiles uses TMS coordinates which have the origin at the bottom left: http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification

Perhaps $z = $z - 1 and $y = pow(2,$z) - $y would do the trick? In MM zoom level 0 is 1 tile, zoom level 1 is 2x2 tiles, etc, but I think in TMS zoom level 0 is 2x2.

RandomEtc commented 13 years ago

Or maybe $y = pow(2, $z) - 1 - $y - leaving $z as you had it? Sorry for random guesses, it's Friday night :)

jhpoosthoek commented 13 years ago

I changed: $y = pow(2, $z-1) - $y; for: $z = $z - 1; $y = pow(2, $z) - 1 - $y; and now it works, thanks!

The next issue I'm trying solve is to continue the map from the dateline onwards. I was able to fit the maps together by: if($x > 0) { $x = $x - 2; } if($x < 0) { $x = $x + 2; } But if you zoom in this creates all sorts of nasty behavior (lower resolution parts next to higher ones, it looks like a mess). Anyone a clue whats going on?

springmeyer commented 13 years ago

See the mapbox/wax code, specifically the connectors/mm which provides a customized getTile method to handle the y flip correctly. And then rest assured that mbtiles will switch to the osm/xyz scheme that mm uses soon to avoid the need for this y flip to TMS.

jhpoosthoek commented 13 years ago

Thanks! Am I correct to say that this code from waxconnector.js does what I need? return this.options.tiles[parseInt(Math.pow(2, coord.zoom) * coord.row + coord.column, 10) % this.options.tiles.length] .replace('{z}', coord.zoom.toFixed(0)) .replace('{x}', coord.column.toFixed(0)) .replace('{y}', coord.row.toFixed(0));

I haven't been able to get wax working yet (no examples found) so I figured I try to add what I need into my code.

tmcw commented 13 years ago

@jhpoosthoek have you seen the Wax manual? It's overflowing with examples.

jhpoosthoek commented 13 years ago

@tmcw, yes I've seen the manual before. I guess I'm used to little example htmls such as created for openlayers and MM. I didn't get the wax examples to work immediately, but now I see that the manual itself also uses wax ;) thanks.

jhpoosthoek commented 13 years ago

I got to it again and the problem is that the wax.mm.connector doesn't seem to work with my tiles: PHP url (the example tiles from mapbox.com on the other hand work perfectly): var tilejson = { tilejson: '1.0.0', scheme: 'tms', tiles: ['http://www.iivision.com/temp/mb2xyz.php?file=ne2&code={Z}/{X}/{Y}'] }; Anyone an idea why this doesn't seem to work?

tmcw commented 13 years ago

Hey, so is this the full natural-earth tileset? Regardless of TMS/XYZ, the url http://www.iivision.com/temp/mb2xyz.php?file=ne2&code=0/0/0 should resolve to a worldwide tile if so.

jhpoosthoek commented 13 years ago

@tmcw, yes it is. I commented out the following lines in the PHP: //$z = $z - 1; //$y = pow(2, $z) - 1 - $y; So now 0/0/0 shows the worldwide tile. But it still doesn't work...

tmcw commented 13 years ago

@jhpoosthoek - this seems to be working fine, are you actually using Wax? http://bl.ocks.org/1149162

jhpoosthoek commented 13 years ago

@tmcw, yes it works! Thanks! I downloaded wax from github, but somehow this just didn't work. The PHP also doesn't work on my localhost through XAMPP. But I don't mind, it works!

I'm working to get also other datasets in: http://www.iivision.com/temp/mb2xyz.php?file=mola&code={z}/{x}/{y}, but I guess I need to do a little bit of GDAL work before I can pass it through the gdal2mb script...

tmcw commented 13 years ago

Great!