2011-05-11 10 views
7

Intento crear un lienzo HTML5 como superposiciónVer el tamaño de un mapa, colocarlo en top:0; left:0;, dibujar algunas cosas en él y agregarlo al mapa Cada vez que el mapa se acerca o se quita, quiero quitar el lienzo viejo del mapa y crear un nuevo lienzo que lo coloque en 0,0 y agregarlo al mapa. Sin embargo, el mapa nunca se reubica en la parte superior: 0; izquierda: 0. ¿Alguien puede ayudar?Lienzo HTML como superposición en Google Maps que se repara en relación con el lienzo del mapa

function CustomLayer(map){ 
this.latlngs = new Array(); 
this.map_ = map; 

this.addMarker = function(position){ 
this.latlngs.push(position); 
} 

this.drawCanvas = function(){ 
this.setMap(this.map_); 
//google.maps.event.addListener(this.map_, 'bounds_changed',this.reDraw()); 
} 

} 

function defineOverlay() { 

CustomLayer.prototype = new google.maps.OverlayView(); 

CustomLayer.prototype.onAdd = function() { 
    console.log("onAdd()"); 
    if(this.canvas){  
    var panes = this.getPanes(); 
    panes.overlayLayer.appendChild(this.canvas); 
    } 
} 


CustomLayer.prototype.remove = function() { 
    console.log("onRemove()"); 
    if(this.canvas) 
    this.canvas.parentNode.removeChild(this.canvas); 
} 


CustomLayer.prototype.draw = function() { 
    console.log("draw()"); 
     this.remove(); 
      this.canvas = document.createElement("canvas"); 
      this.canvas.setAttribute('width', '800px'); 
      this.canvas.setAttribute('height', '480px'); 
      this.canvas.setAttribute('top', '30px'); 
      this.canvas.setAttribute('left', '30px'); 
      this.canvas.setAttribute('position', 'absolute'); 
      this.canvas.setAttribute('border', '1px solid red'); 
      this.canvas.style.border = '1px solid red'; 

      //using this way for some reason scale up the images and mess up the positions of the markers 
      /*this.canvas.style.position = 'absolute'; 
      this.canvas.style.top = '0px'; 
      this.canvas.style.left = '0px'; 
      this.canvas.style.width = '800px'; 
      this.canvas.style.height = '480px'; 
      this.canvas.style.border = '1px solid red';*/ 

      //get the projection from this overlay 
      overlayProjection = this.getProjection(); 
      //var mapproj = this.map_.getProjection(); 

       if(this.canvas.getContext) { 
        var context = this.canvas.getContext('2d'); 
        context.clearRect(0,0,800,480); 

        for(i=0; i<this.latlngs.length; i++){ 

         p = overlayProjection.fromLatLngToDivPixel(this.latlngs[i]); 
         //p = mapproj.fromLatLngToPoint(this.latlngs[i]); 
         img = new Image(); 
         img.src = "standardtick.png"; 
          console.log(Math.floor(p.x)+","+Math.floor(p.y)); 
        context.drawImage(img,p.x,p.y); 
        } 
       } 
    this.onAdd();   
    console.log("canvas width:"+this.canvas.width+" canvas height: "+this.canvas.height); 
    console.log("canvas top:"+this.canvas.getAttribute("top")+" left: "+this.canvas.getAttribute("left")); 
} 
} 

Respuesta

0

Una vez que sus mapa se mueve, el contexto dibujo tiene que saber que se ha movido.

CustomOverlayView.prototype.alignDrawingPane = function(force) { 
    window.mapProjection = this.getProjection(); 
    var center = window.mapProjection.fromLatLngToDivPixel(map.getCenter()); 
    //My drawing container is dragged along with the map when panning 
    //this.drawPane refers to any node in MapPanes retrieved via this.getPanes() 
    this.drawPane.css({left:center.x - (mapWidth/2), top:center.y-(mapHeight/2)}); 
}; 

Llámalo en el método draw(). Asegúrese de que su sorteo se llama cuando haya terminado de arrastre:

google.maps.event.addListener(map, 'dragend', function() { 
    myCustomOverlay.draw(); 
}); 
5

En este ejemplo - Creo que es importante llamar la atención sobre la diferencia entre projection.fromLatLngToDivPixel y projection.fromLatLngToContainerPixel. En este contexto, DivPixel se usa para mantener la posición del lienzo centrada sobre la vista del mapa, mientras que ContainerPixel se usa para encontrar las posiciones de las formas que está dibujando en el lienzo.

Lo que sigue es un ejemplo de trabajo completo que resolví mientras jugaba con este problema yo mismo.

Obligatorio Propiedades de CSS para la superposición:

.GMAPS_OVERLAY 
    { 
    border-width: 0px; 
    border: none; 
    position:absolute; 
    padding:0px 0px 0px 0px; 
    margin:0px 0px 0px 0px; 
    } 

inicializar el mapa y crear una prueba basada en Google Marcadores

var mapsize = { width: 500, height: 500 }; 
    var mapElement = document.getElementById("MAP"); 

    mapElement.style.height = mapsize.width + "px"; 
    mapElement.style.width = mapsize.width + "px"; 

    var map = new google.maps.Map(document.getElementById("MAP"), { 
    mapTypeId: google.maps.MapTypeId.TERRAIN, 
    center: new google.maps.LatLng(0, 0), 
    zoom:  2 
    }); 

    // Render G-Markers to Test Proper Canvas-Grid Alignment 
    for (var lng = -180; lng < 180; lng += 10) 
    { 
    var marker = new google.maps.Marker({ 
     position: new google.maps.LatLng(0, lng), 
     map: map 
    }); 
    } 

Definir la superposición personalizada

var CanvasOverlay = function(map) { 
    this.canvas   = document.createElement("CANVAS"); 
    this.canvas.className = "GMAPS_OVERLAY"; 
    this.canvas.height = mapsize.height; 
    this.canvas.width  = mapsize.width; 
    this.ctx    = null; 
    this.map    = map; 

    this.setMap(map); 
    }; 
    CanvasOverlay.prototype = new google.maps.OverlayView(); 

    CanvasOverlay.prototype.onAdd = function() { 
    this.getPanes().overlayLayer.appendChild(this.canvas); 
    this.ctx = this.canvas.getContext("2d"); 
    this.draw(); 
    }; 

    CanvasOverlay.prototype.drawLine = function(p1, p2) { 
    this.ctx.beginPath(); 
    this.ctx.moveTo(p1.x, p1.y); 
    this.ctx.lineTo(p2.x, p2.y); 
    this.ctx.closePath(); 
    this.ctx.stroke(); 
    }; 

    CanvasOverlay.prototype.draw = function() { 
    var projection = this.getProjection(); 

    // Shift the Canvas 
    var centerPoint = projection.fromLatLngToDivPixel(this.map.getCenter()); 
    this.canvas.style.left = (centerPoint.x - mapsize.width/2) + "px"; 
    this.canvas.style.top = (centerPoint.y - mapsize.height/2) + "px"; 

    // Clear the Canvas 
    this.ctx.clearRect(0, 0, mapsize.width, mapsize.height); 

    // Draw Grid with Canvas 
    this.ctx.strokeStyle = "#000000"; 
    for (var lng = -180; lng < 180; lng += 10) 
    { 
     this.drawLine(
     projection.fromLatLngToContainerPixel(new google.maps.LatLng(-90, lng)), 
     projection.fromLatLngToContainerPixel(new google.maps.LatLng(90, lng)) 
    ); 
    } 
    }; 

La inicialización del lienzo

me parece que me gusta añadir una llamada adicional para dibujar en el evento "dragend" -, pero probarlo para ver lo que usted piensa en sus necesidades.

var customMapCanvas = new CanvasOverlay(map); 
    google.maps.event.addListener(map, "drawend", function() { 
    customMapCanvas.draw(); 
    }; 

En los casos en lienzo de dibujo está desacelerando Mapa

En las aplicaciones con las que trabajo, me parece que el Marco Mapa llama al método 'dibujar' con demasiada frecuencia en la lona que son dibujando algo que toma un segundo o más para completar. En este caso, defino el 'dibujar' prototipo de la función a ser simplemente una función de vacío mientras nombrar mi función draw real como 'canvasDraw' - a continuación, añadir detectores de eventos para "ZoomEnd" y "dragend". Lo que obtienes aquí es un lienzo que se actualiza solo después de que un usuario cambia el nivel de zoom o al final de una acción de arrastre del mapa.

CanvasOverlay.prototype.draw = function() { };  

    ... 

    google.maps.event.addListener(map, "dragend", function() { 
    customMapCanvas.canvasDraw(); 
    }); 

    google.maps.event.addListener(map, "zoom_changed", function() { 
    customMapCanvas.canvasDraw(); 
    }); 

demostración en vivo: Complete Example - All Inline Source

+0

John, este es un excelente ejemplo.¿Alguna posibilidad de que la hayas actualizado a Google maps V3? He intentado aquí: http://jsfiddle.net/rogerguess/Lxdqtqdn/11/ el zoom está funcionando pero el arrastre no está – Roger

Cuestiones relacionadas