Is Leaflet a good tool for non-map images? [closed

2019-01-12 17:55发布

问题:

I am writing a web app that involves navigating technical illustrations (pan, zoom, click). I assume that Cloudmade Leaflet a good tool for this, only because someone used it to make XKCD 1110 pan/zoomable and I really like how it turned out.

Obviously, I would need to tile and scale my original technical illustration, but let's say that's a trivial problem that I have solved. Looking at the Leaflet API, however, it appears I would have to convert my tech illustrations (.ai, .svg, and .png files) to a geographical standard like GeoJSON. That seems like an awkward proposition.

Can anyone recommend Leaflet, or any other tool, for navigating non-map imagery?

回答1:

You can do this with Leaflet. (I have done exactly this myself.)

You do have to convert your pixel sizes to latlong (latitude/longitude). Leaflet provides you an easy way to do that by using the Simple "Coordinate Reference System", map.project and map.unproject.

First, construct your map like this:

var map = L.map('map', {
  maxZoom: 20,
  minZoom: 20,
  crs: L.CRS.Simple
}).setView([0, 0], 20);

…and then set the map bounds (for an image that is 1024x6145):

var southWest = map.unproject([0, 6145], map.getMaxZoom());
var northEast = map.unproject([1024, 0], map.getMaxZoom());
map.setMaxBounds(new L.LatLngBounds(southWest, northEast));

There's more details regarding splitting your images available here including a Ruby gem which might also be useful.



回答2:

This works for images that are not tiled.

function init() {
    var map = L.map('map', {
        maxZoom: 24,
        minZoom: 1,
        crs: L.CRS.Simple
    }).setView([0, 0], 1);

    map.setMaxBounds(new L.LatLngBounds([0,500], [500,0]));

    var imageUrl = 'http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg'
    var imageBounds = [[250,0], [0,250]];

    L.imageOverlay(imageUrl, imageBounds).addTo(map);
}


回答3:

I am using Leaflet for maps with custom tiles with geoinformation, but as far as I can see Leaflet should be able to do this task. There are some points to consider how you should organize your images to be able to display them in a pannable and zoomable way:

First of all, you have to understand the concept behind map navigation and the corresponding tile filenames. This concept is a QuadTree. An example on how this works can be found here.

Then you have to cut your raw technical illustrations in different tiles. If you start on one zoom level only, this should be quite straightforward. You can then use the tiles in a new Leaflet TileLayer. When you want to have zooming, it might get a little bit more difficult. You will have to find out the correct boundaries for your tiles and construct the correct filenames (see the QuadTree references above).

To sum up: Leaflet should not be a problem in your task. The main task for you is to create suitable and correct tiles from your raw data.



回答4:

I've had good luck with MapTiller -- http://www.maptiler.com/



回答5:

If you want a non-tile option, you can do the entire thing clientside without tile pre-cutting

See https://github.com/Murtnowski/GMap-JSlicer

slicer = new JSlicer(document.getElementById('map'), 'myImage.png');
slicer.init();

Very simple.



回答6:

The biggest issue in using Leaflet is figuring out how the tiles have to be generated, ordered, and then correctly make the calls so that everything appears as you expect. After a few days hopelessly trying out solution after solution, this was the only one that worked for me, thanks to a tutorial done by Pedro Sousa:

https://build-failed.blogspot.pt/2012/11/zoomable-image-with-leaflet.html

In essence, this uses GDAL2Tiles to correctly split tiles in a predictable way. This is the kind of tool that is easily available on most Linux distributions (and allegedly it runs fine under Mac OS X as well, using ports or a similar thing). There is no watermarking, limitation on size, etc. whatsoever with this tool. Place the tiles on directories of your server just like Pedro Sousa explains in his article.

Leaflet will then load a 'map' using your tiles with 'fake' geo coordinates, using the raster file's size to calculate the 'fake' longitude/latitude correctly. After that, you can pretty much do with it whatever you wish, just like any other map tile server. In my case, I only needed to drop some markers, so I couldn't care less in what coordinate system I was working on — the function below was useful to extract the 'fake' geo coordinates in order to know where to place the markers:

var popup = L.popup();
function onMapClick(e) {
    popup
        .setLatLng(e.latlng)
        .setContent("You clicked the map at " + e.latlng.toString() + "\nZoom level is " + map.getZoom())
        .openOn(map);
}
map.on('click', onMapClick);

I did manage to successfully replace an old Flash-based map navigator using Leaflet and basically replicate almost every Flash functionality (even using the same markers and all!). With, of course, the advantage that Leaflet will work on iOS devices