Как я могу наложить схемы SVG на Google Maps?

Мнение: разработчики должны тестировать свой собственный код

Я видел слишком много дерьма, переданного для тестирования, только для того, чтобы оно фактически не исправляло данную ошибку, что влечет за собой коммуникационные издержки и поощрение безответственной практики.

17
задан Jason Plank 8 October 2011 в 17:02
поделиться

3 ответа

Вот некоторые новости (я надеюсь, что лучше поместить их здесь в ответ, а не редактировать свои вопросы или создавать новый вопрос. Пожалуйста, не стесняйтесь переместить его, если необходимо, или в скажите мне, чтобы я мог исправить):

Моя проблема заключалась в следующем:

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

не работал в Safari 3, Firefox и Opera (IE не позволяет рисовать SVG).

Фактически, этот код произвести вставку (в

) следующего элемента

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

. И Safari 4 может рисовать файл SVG как изображение, но это не способ сделать для другого браузера. Итак, теперь идея состоит в том, чтобы создать собственный оверлей для SVG, как описано здесь .

Это причина, по которой я задал этот вопрос (извините, но HTML / javascript не мои самые сильные стороны).

А поскольку в Webkit есть небольшая ошибка для рендеринга SVG с прозрачным фоном с элементом , мне нужно использовать или в соответствии с браузером (мне это не нравится, но ... на данный момент это все еще быстрые и грязные эксперименты)

Итак, я начал с этого кода (работа все еще продолжается):

// 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);
} 

...

Функция draw еще не написана.

У меня все еще есть проблема (я медленно прогрессирую, благодаря тому, что я читаю / узнаю везде, а также благодаря людям, которые отвечают на мои вопросы).

Теперь проблема заключается в следующем: с тегом карту нельзя перетаскивать. Во всем элементе указатель мыши не является «значком руки» для перетаскивания карты, а просто обычный указатель.

И я не нашел, как это исправить. Следует ли мне добавить новое событие мыши (я только что видел событие мыши, когда добавляется щелчок или двойной щелчок, но не для перетаскивания карты ...)?

Или есть другой способ добавить этот слой, чтобы сохранить возможность перетаскивания?

Спасибо за ваши комментарии и ответы.

PS: Я также пытаюсь добавлять один за другим элементы моего SVG, но ... на самом деле ... я не знаю, как чтобы добавить их в дерево DOM. В этом примере SVG читается и анализируется с помощью GXml.parse () , и получаются все элементы с заданным именем тега ( xml.documentElement.getElementsByTagName ) и добавлен к узлу SVG ( svgNode.appendChild (node) ). Но в моем случае мне нужно напрямую добавить дерево SVG / XML (добавить все его элементы), и есть разные теги ( , , , и т. д.). Это может быть проще, но я не знаю, как это сделать ..: (

6
ответ дан 30 November 2019 в 14:21
поделиться

Этот вопрос кратко обсуждался в группе API Карт Google . Вот что они сказали:

Я не пробовал, но SVG - это подмножество XML, поэтому вы можете читать их с помощью GDownloadUrl () и проанализируйте их с помощью GXml.parse (). На некоторых нестабильных веб-серверах возможно, вам придется изменить файл расширение в XML.

Затем вам нужно просмотреть XML DOM, написание SVG, который вы найдете с помощью document.createElementNS () и .setAttribute () вызывает ...

Также есть несколько примеров SVG Карт Google здесь и здесь .

Удачи!

2
ответ дан 30 November 2019 в 14:21
поделиться

Я провёл последний вечер над этой проблемой и, наконец, нашел решение своей проблемы.

Это было не так уж сложно.

Идея в том, как сказал Крис Б. , чтобы загрузить файл SVG с помощью GDownloadUrl, проанализируйте его с помощью GXml.parse () и добавьте в дерево DOM все необходимые мне элементы SVG

Для упрощения я предположил, что все элементы SVG были помещены в большую группу под названием " mainGroup ". Я также предполагал, что некоторые элементы могут быть в файле.

Итак, вот библиотека, основанная на пользовательских наложениях Google Maps :

// 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);
}   

Таким образом, вы можете использовать его точно так же, как функцию GGroundOverlay , за исключением того, что ваш файл SVG должен быть создан с проекцией Меркатора (но если вы примените его на небольшой площади, например, в одном городе или меньше , вы не увидите разницы).

Это должно работать с Safari, Firefox и Opera. Вы можете попробовать мой небольшой пример здесь

Скажите, что вы думаете об этом.

6
ответ дан 30 November 2019 в 14:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: