Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在Google地图上覆盖SVG图表?_Javascript_Google Maps_Svg - Fatal编程技术网

Javascript 如何在Google地图上覆盖SVG图表?

Javascript 如何在Google地图上覆盖SVG图表?,javascript,google-maps,svg,Javascript,Google Maps,Svg,我想在谷歌地图上添加一个覆盖图。该图像是我生成的一个SVG文件(带有SVGFig的Python) 我正在使用以下代码: if (GBrowserIsCompatible()) { var map = new GMap2(document.getElementById("map_canvas")); map.setCenter(new GLatLng(48.8, 2.4), 12);     // ground overlay     var boundaries = new G

我想在谷歌地图上添加一个覆盖图。该图像是我生成的一个SVG文件(带有SVGFig的Python)

我正在使用以下代码:

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);
}
// 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";
}
令人惊讶的是,它与Safari 4兼容,但与Firefox不兼容(对于Safari 3,背景是不透明的)

有人知道如何覆盖SVG吗

PS1:我读过一些作品,比如或swa.ethz.ch/googlemaps的源代码,但似乎他们必须使用JavaScript代码来解析SVG并逐个添加所有元素(但我不了解所有源代码…)

PS2:SVG由不同的填充路径和圆组成,具有透明度。 如果没有覆盖SVG的解决方案,我可以使用两种替代解决方案:

  • 光栅化SVG
  • 在GPolygons中转换路径和圆
但是我不太喜欢第一种解决方案,因为位图的质量很差,而且需要时间生成抗锯齿


对于第二种解决方案,圆弧、椭圆和圆必须分解为小的多段线。要想取得好的成绩,他们中的很多人都是必不可少的。但是我有大约3000个弧和圆要画,所以…

这个问题在网上被简要讨论过。他们是这么说的:

我没有尝试过,但是SVG是一个子集 XML,因此您可以使用 GDownloadUrl()并使用 GXml.parse()。在一些不可靠的Web服务器上 您可能必须更改该文件 对XML的扩展

然后必须在XML中爬行 DOM,编写您找到的SVG 使用document.createElements()和 .setAttribute()调用

还有一些Google Maps SVG示例和示例

祝你好运

以下是一些新闻(我希望最好将它们放在这里作为答案,而不是编辑我的问题或创建一个新问题。如果需要,请随意移动它,或者告诉我,以便我可以更正):

我的问题是:

var oldmap = new GGroundOverlay("test.svg", boundaries);
map.addOverlay(oldmap);
不适用于Safari 3、Firefox和Opera(即无法绘制SVG)

事实上,此代码生成以下元素的插入(在
中)

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

Safari 4能够将SVG文件绘制为图像,但这不是其他浏览器的方式。因此,现在的想法是为SVG创建一个自定义覆盖,如前所述

这就是我要求的原因(很抱歉,HTML/javascript不是我的强项)

由于Webkit中有一个小错误,用于使用
元素呈现具有透明背景的SVG,因此我需要使用

尚未编写
draw
函数

我仍然有一个问题(我进步缓慢,这要感谢我在各地读到的东西,也要感谢那些回答我问题的人)

现在,问题是:使用
标记时,地图无法拖动。在
元素中,鼠标指针不是用来拖动地图的“手形图标”,而是普通的指针

我没有发现如何纠正这一点。我应该添加一个新的鼠标事件(我只是在单击或双击附加时看到鼠标事件,但不是为了拖动地图…)

或者是否有其他方法添加此层以保持拖动能力

谢谢你的评论和回答


PS:我也尝试一个接一个地添加SVG的元素,但是。。。事实上我不知道如何将它们添加到DOM树中。在中,使用
GXml.parse()
读取和解析SVG,并获取具有给定标记名的所有元素(
xml.documentElement.getElementsByTagName
)并添加到SVG节点(
svgNode.appendChild(节点)
)。但是在我的例子中,我需要直接添加SVG/XML树(添加其所有元素),并且有不同的标记(
,等等)。这可能更简单,但我不知道怎么做(

我把最后一个晚上花在这个问题上,终于找到了解决问题的办法

这并不难

正如Chris B.所说,这个想法是用GDownloadUrl加载SVG文件,用GXml.parse()解析它,并在DOM树中添加我需要的每个SVG元素

为了简化,我假设所有SVG元素都放在一个名为“mainGroup”的大组中。我还假设一些元素可以在文件中

这是图书馆,基于:

因此,您可以像使用
GGroundOverlay
功能一样使用它,只是SVG文件应该使用墨卡托投影创建(但是如果您将其应用于小区域,例如一个城市或更小的区域,您将看不到区别)

这应该适用于Safari、Firefox和Opera


告诉我你是怎么想的。

这是一个多么好的问题。我的直觉是,你的第二种方法不会起作用,但在没有确认gmaps如何处理这么多的多段线的情况下,我会犹豫回答。我期待着看一看这是怎么回事。可能是GGP过度使用CSS背景图像吗?FF无法处理(然而,3.5会)SVG作为背景。我只是尝试使用FF 3.5,但它也不起作用。事实上,当我查看下载的媒体(工具/页面信息/媒体)时,我的SVG根本没有加载…GGroundOverlays不使用CSS背景图像。只是普通的img。我不知道它们为什么不起作用。你可以(尝试)看到结果好的,谢谢链接。是的,也许我可以加载我的文件,解析它并逐个插入我所有的SVG元素。我会尝试,即使这个解决方案不能说服我…我已经能够使用GGroundOverlay(“test.SVG”,bounders)一步加载,但只有使用Safari 4…我会告诉你这是怎么回事
// 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";
}
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);
}