Me gustaría añadir una superposición de la imagen en un Mapa de Google. La imagen es un archivo SVG he generado (Python con SVGFig).

Estoy usando el siguiente código:

if (GBrowserIsCompatible()) {
    var map = new GMap2(document.getElementById("map_canvas"));
    map.setCenter(new GLatLng(48.8, 2.4), 12);

    //ground overlay
    var boundaries = new GLatLngBounds(new GLatLng(48.283188032632829, 1.9675270369830129), new GLatLng(49.187215000000002, 2.7771877478303999));
    var oldmap = new GGroundOverlay("test.svg", boundaries);
    map.addControl(new GSmallMapControl());
    map.addControl(new GMapTypeControl());
    map.addOverlay(oldmap);
}

Sorprendentemente, funciona con Safari 4, pero no funciona con Firefox (con Safari 3, el fondo no es transparente).

¿Alguien tiene una idea de cómo podría superposición de un SVG?

PS1: he leído algunas obras como este o el código fuente de la swa.ethz.ch/googlemaps, pero parece que tienen que utilizar el código JavaScript para analizar el SVG y agregar uno por uno todos los elementos (pero yo no entendía todo a la fuente…).

PS2: El archivo SVG se compone de diferentes lleno de caminos y círculos, con la transparencia.
Si no hay solución a la superposición de mi SVG, puedo usar 2 soluciones alternativas:

  • rasterizar el SVG
  • convertir las rutas y los círculos en GPolygons

Pero no me gusta mucho la 1 de la solución debido a la mala calidad del mapa de bits y el tiempo para generar con antialiasing.

Y para la 2ª solución, los arcos, elipses y círculos tendrán que ser descompuestos en pequeñas polilíneas. Muchos de ellos serán necesarias para un buen resultado. Pero tengo alrededor de 3000 arcos y círculos para dibujar, así que…

  • Qué gran pregunta. Mis entrañas siento es que su segundo enfoque no funcionará, pero dudó en responder sin confirmar cómo gmaps realiza con que el volumen de las polilíneas. Espero a ver cómo va todo.
  • No podía ser, que GGroundOverly hace uso de CSS imágenes de fondo? FF no se manejan (sin embargo, 3.5) SVGs como fondos.
  • Acabo de probar con FF 3.5, pero no funciona, también. De hecho, cuando estoy buscando en la descarga de los medios de comunicación (Herramientas/Página de Información/Medios de comunicación), mi SVG no está cargado en todos los…
  • GGroundOverlays no usar CSS imágenes de fondo. Sólo regular de img. No sé por qué no funcionan.
  • Usted puede (intentar) para ver el resultado de aquí
InformationsquelleAutor ThibThib | 2009-06-28

3 Comentarios

  1. 6

    Aquí están algunas noticias (espero que sea mejor para ponerlos aquí en una respuesta, en lugar de editar mis preguntas o para crear una nueva pregunta. Por favor, siéntase libre de moverlo si es necesario, o para decirlo de mí, así como yo puede rectificar):

    Mi problema era el siguiente:

    var oldmap = new GGroundOverlay("test.svg", boundaries);
    map.addOverlay(oldmap);

    no funciona en Safari 3, Firefox y Opera (es decir, no se permiten dibujar SVG).

    De hecho, este código producir la inserción (en un <div>) de la siguiente elemento

    <img src="test.svg" style=".....">

    Y Safari 4 es capaz de dibujar un archivo pdf como una imagen, pero esta no es la manera de hacerlo para el resto de los navegadores. Así que ahora la idea es crear una personalizada de superposición para el SVG, como se explica aquí.

    Esa es la razón por la que me pidió esta pregunta (lo siento, pero HTML/javascript no son mis puntos fuertes).

    Y ya que hay un pequeño error con el motor Webkit para la representación de un SVG con fondo transparente con <object>elemento, necesito usar <object> o <img> en consecuencia para el navegador (no me gusta esto, pero… por el momento, todavía la rápida y desordenada experimentos)

    Así que empecé con este código (todavía en desarrollo):

    //create the object
    function myOverlay(SVGurl, bounds)
    {
        this.url_ = SVGurl;
        this.bounds_ = bounds;
    }
    
    //prototype
    myOverlay.prototype = new GOverlay();
    
    //initialize
    myOverlay.prototype.initialize = function(map)
    {
        //create the div
        var div = document.createElement("div");
        div.style.position = "absolute";
        div.setAttribute('id',"SVGdiv");
        div.setAttribute('width',"900px");
        div.setAttribute('height',"900px");
    
        //add it with the same z-index as the map
        this.map_ = map;
        this.div_ = div;
    
        //create new svg root element and set attributes
        var svgRoot;
        if (BrowserDetect.browser=='Safari')
        {
            //Bug in webkit: with <objec> element, Safari put a white background... :-(
            svgRoot = document.createElement("img");
            svgRoot.setAttribute("id", "SVGelement");
            svgRoot.setAttribute("type", "image/svg+xml");
            svgRoot.setAttribute("style","width:900px;height:900px");
            svgRoot.setAttribute("src", "test.svg");
        }
        else //if (BrowserDetect.browser=='Firefox')
        {
            svgRoot = document.createElement("object");
            svgRoot.setAttribute("id", "SVGelement");
            svgRoot.setAttribute("type", "image/svg+xml");
            svgRoot.setAttribute("style","width:900px;height:900px;");
            svgRoot.setAttribute("data", "test.svg");
        }
    
    
        div.appendChild(svgRoot);
        map.getPane(G_MAP_MAP_PANE).appendChild(div);
    
        //this.redraw(true);
    } 
    
    ...

    La draw función aún no está escrito.

    Todavía tengo un problema (me progresar lentamente, gracias a lo que he leído/aprender en todas partes, y también gracias a la gente que responda a mis preguntas).

    Ahora, el problema es el siguiente : con el <object> etiqueta, el mapa no es arrastrarse. Todo el <object> elemento, el puntero del ratón no es «el icono de la mano» para arrastrar el mapa, pero solo la normal puntero.

    Y no encontré cómo corregir este problema. Debo agregar un nuevo evento de ratón (acabo de ver el evento del ratón cuando un clic o un doble clic en agregar, pero no para arrastrar el mapa…) ?

    O hay otra forma de añadir esta capa con el fin de preservar la funcionalidad de arrastrar capacidad ?

    Gracias por sus comentarios y respuestas.

    PS: yo también intente agregar uno por uno los elementos de mi SVG, pero… en realidad… no sé cómo agregarlos en el árbol DOM. En este ejemplo, el formato SVG se lee y se analiza con GXml.parse(), y todos los elementos con un determinado nombre de la etiqueta se obtienen (xml.documentElement.getElementsByTagName) y se añade el SVG nodo (svgNode.appendChild(node)). Pero en mi caso, necesito agregar directamente el SVG/árbol XML (agregar todos sus elementos), y hay diferentes etiquetas (<defs>, <g>, <circle>, <path>, etc.). Se puede ser más sencillo, pero no sé cómo hacerlo.. 🙁

  2. 6

    Puedo pasar la última noche en este problema, y finalmente encontré la solución para mi problema.

    No fue tan difícil.

    La idea es, como Chris B. dijo, para cargar el archivo SVG con GDownloadUrl, analizar con GXml.parse() y agregar en el árbol DOM cada SVG elementos necesito

    Para simplificar, he supone que todos los elementos SVG fue puesto en un gran grupo llamado «mainGroup». También he supone que algunos elementos pueden estar en el archivo.

    Así que aquí está la biblioteca, basada en la Google Maps Personalizado Superposiciones:

    //create the object
    function overlaySVG( svgUrl, bounds)
    {
    this.svgUrl_ = svgUrl;
    this.bounds_ = bounds;
    }
    //prototype
    overlaySVG.prototype = new GOverlay();
    //initialize
    overlaySVG.prototype.initialize = function( map)
    {
    //create new div node 
    var svgDiv = document.createElement("div");
    svgDiv.setAttribute( "id", "svgDivison");
    //svgDiv.setAttribute( "style", "position:absolute");
    svgDiv.style.position = "absolute";
    svgDiv.style.top = 0;
    svgDiv.style.left = 0;
    svgDiv.style.height = 0;
    svgDiv.style.width = 0;
    map.getPane(G_MAP_MAP_PANE).appendChild(svgDiv);
    //create new svg element and set attributes
    var svgRoot = document.createElementNS( "http://www.w3.org/2000/svg", "svg");
    svgRoot.setAttribute( "id", "svgRoot");
    svgRoot.setAttribute( "width", "100%");
    svgRoot.setAttribute( "height","100%");
    svgDiv.appendChild( svgRoot);
    //load the SVG file
    GDownloadUrl( this.svgUrl_, function( data, responseCode)
    {
    var xml = GXml.parse(data);
    //specify the svg attributes
    svgRoot.setAttribute("viewBox", xml.documentElement.getAttribute("viewBox"));
    //append the defs
    var def = xml.documentElement.getElementsByTagName("defs");
    //for( var int=0; i<def.length; i++)
    svgRoot.appendChild(def[0].cloneNode(true));
    //append the main group
    var nodes = xml.documentElement.getElementsByTagName("g");
    for (var i = 0; i < nodes.length; i++)
    if (nodes[i].id=="mainGroup")
    svgRoot.appendChild(nodes[i].cloneNode(true));
    });
    //keep interesting datas
    this.svgDiv_ = svgDiv;
    this.map_ = map;
    //set position and zoom
    this.redraw(true);
    }
    //remove from the map pane
    overlaySVG.prototype.remove = function()
    {
    this.div_.parentNode.removeChild( this.div_);
    }
    //Copy our data to a new overlaySVG...
    overlaySVG.prototype.copy = function()
    {
    return new overlaySVG( this.url_, this.bounds_, this.center_);
    }
    //Redraw based on the current projection and zoom level...
    overlaySVG.prototype.redraw = function( force)
    {
    //We only need to redraw if the coordinate system has changed
    if (!force) return;
    //get the position in pixels of the bound
    posNE = map.fromLatLngToDivPixel(this.bounds_.getNorthEast());      
    posSW = map.fromLatLngToDivPixel(this.bounds_.getSouthWest());
    //compute the absolute position (in pixels) of the div ...
    this.svgDiv_.style.left = Math.min(posNE.x,posSW.x) + "px";
    this.svgDiv_.style.top = Math.min(posSW.y,posNE.y) + "px";
    //... and its size
    this.svgDiv_.style.width = Math.abs(posSW.x - posNE.x) + "px";
    this.svgDiv_.style.height = Math.abs(posSW.y - posNE.y) + "px";
    }

    Y, se puede utilizar con el siguiente código:

    if (GBrowserIsCompatible())
    {
    //load map
    map = new GMap2(document.getElementById("map"), G_NORMAL_MAP);
    //create overlay   
    var boundaries = new GLatLngBounds( new GLatLng(48.2831, 1.9675), new GLatLng(49.1872, 2.7774));
    map.addOverlay( new overlaySVG( "test.svg", boundaries ));
    //add control and set map center
    map.addControl(new GLargeMapControl());
    map.setCenter(new GLatLng(48.8, 2.4), 12);
    }   

    Así, usted puede utilizar exactamente como se utiliza el GGroundOverlay función, excepto que su archivo SVG debe ser creado con la proyección de Mercator (pero si te lo aplicas en el área pequeña, como una ciudad o pequeño, usted no va a ver la diferencia).

    Esto debería funcionar con Safari, Firefox y Opera. Puede probar mi pequeño ejemplo aquí

    Dime ¿qué piensa usted acerca de él.

    • Ejemplo impresionante!
  3. 2

    Esta cuestión se discutió brevemente en el El API de Google Maps Grupo. He aquí lo que dijo:

    No lo he probado, pero SVG es un subconjunto
    de XML, por lo que se puede leer con ellos
    GDownloadUrl() y analizarlos con
    GXml.parse(). En algunos wonky servidores web
    puede que tenga que cambiar el archivo
    extensión XML.

    Entonces usted tiene que arrastrarse a través de XML
    DOM, escribir el SVG que puedes encontrar
    con el documento.createElementNS() y
    .setAttribute() llama…

    También hay algunos Mapas de Google SVG ejemplos aquí y aquí.

    Buena suerte!

    • Ok, gracias por el enlace. Sí, tal vez puedo cargar mi archivo, analizar e insertar uno por uno todos mis elementos SVG. Voy a intentar, incluso si esta solución no me convence… Y ya soy capaz de cargar en un solo paso, con GGroundOverlay(«prueba.svg», de los límites), pero sólo con Safari 4… os contaré cómo va todo

Dejar respuesta

Please enter your comment!
Please enter your name here