2012-10-31 19 views
6

Im usando leaflet per creare una mappa fotografica, con le mie tessere, che funziona come previsto.Aggiunta di ulteriori livelli di zoom nelle mappe dei contatori

Im cercando di capire come posso impedire che lo zoom da seguendo questo Quadtree tipo di pattern:

  • Livello zoom 0 - mappa intera larghezza = 256px;
  • Livello di zoom 1 - Larghezza intera mappa = 512 px;
  • Livello di zoom 2 - Larghezza intera mappa = 1024px;
  • E così via ...

mi piacerebbe essere in grado di ingrandire dire con incrementi del 25% o 100px.

Un esempio di 100px incrementi:

  • Zoom Livello 0 - mappa intera larghezza = 200px;
  • Livello di zoom 1 - Larghezza intera mappa = 300 px;
  • Livello di zoom 2 - Larghezza intera mappa = 400 px;
  • E così via ...

Domanda: Qual è la logica per fare questo? Se è possibile?


Il motivo per voler fare questo è così che la mia mappa foto (che pretende molto avvolgere come una mappa normale) può essere più responsive e montare gli utenti Dimensioni dello schermo piacevolmente.

ho fatto una dimostrazione del mio problema che può essere visto here

risposta

8

La risposta breve è che è possibile visualizzare solo i livelli di zoom per cui è stata tessere pre-renderizzati. Il volantino non creerà per te livelli di zoom intermedi.

La risposta lunga è che per poter utilizzare fare questo, è necessario definire il proprio metodo di scala CRS e passare alla mappa, per esempio:

L.CRS.CustomZoom = L.extend({}, L.CRS.Simple, { 
    scale: function (zoom) { 
     // This method should return the tile grid size 
     // (which is always square) for a specific zoom 
     // We want 0 = 200px = 2 tiles @ 100x100px, 
     // 1 = 300px = 3 tiles @ 100x100px, etc. 
     // Ie.: (200 + zoom*100)/100 => 2 + zoom 

     return 2 + zoom; 
    } 
}); 

var map = L.map('map', { crs: L.CRS.CustomZoom }).setView([0, 0], 0); 

In questo esempio, ho esteso L.CRS.Simple, ma puoi naturalmente estendere qualsiasi CRS dall'API che desideri o persino crearne di nuovi.

Utilizzando un fattore di zoom che si traduce in una dimensione di pixel della mappa che non è un multiplo della tessera, significa che le tessere del bordo destro/inferiore saranno riempite solo parzialmente con i dati della mappa. Questo può essere risolto rendendo la parte non mappa di tali tessere trasparente al 100% (o lo stesso colore del tuo sfondo).

Tuttavia, è, secondo me, un'idea molto migliore per impostare il tilesize in modo che corrisponda al minimo comune denominatore, in questo caso 100px. Ricordarsi di riflettere questo utilizzando l'opzione tileSize nel layer Tile. E, naturalmente, dovrai ri-renderizzare l'immagine in riquadri da 100x100 pixel invece dei riquadri 256x256 che stai utilizzando al momento.

Un avvertimento, la versione corrente di LeafletJS (0.5) presenta un bug che impedisce il funzionamento di un metodo scale() personalizzato, a causa del fatto che la classe TileLayer viene codificata per utilizzare il ridimensionamento dello zoom di potenza 2. Tuttavia, il cambiamento che devi fare è minore e spero che questo sia affrontato in una futura versione di Leaflet. Basta cambiare TileLayer._getWrapTileNum() da:

_getWrapTileNum: function() { 
    // TODO refactor, limit is not valid for non-standard projections 
    return Math.pow(2, this._getZoomForUrl()); 
}, 

A:

_getWrapTileNum: function() { 
    return this._map.options.crs.scale(this._getZoomForUrl()); 
}, 
+1

Se non si dispone di piastrelle pre resi per ogni livello di zoom, può utilizzare in qualche modo Opuscolo piastrelle livello di zoom elevati e li scala e usare quelli? Anche se sarebbero leggermente pixelati? –

Problemi correlati