Подтвердить что ты не робот

Как использовать маркеры SVG в API Карт Google v3

Могу ли я использовать преобразованный image.svg как значок google map. Я преобразовал свой png-образ в svg, и я хочу использовать его как символ карты google, который можно повернуть. Я уже пытался использовать символ карты google, но я хочу иметь значок, такой как автомобиль, человек и т.д.... почему я переработал некоторые png файлы в svg. как этот примерный сайт, что он использует для этих http://www.goprotravelling.com/

4b9b3361

Ответ 1

Вы можете отобразить свой значок с помощью нотации SVG Path.

Подробнее см. документацию Google.

Вот пример:

var icon = {

    path: "M-20,0a20,20 0 1,0 40,0a20,20 0 1,0 -40,0",
    fillColor: '#FF0000',
    fillOpacity: .6,
    anchor: new google.maps.Point(0,0),
    strokeWeight: 0,
    scale: 1
}

var marker = new google.maps.Marker({
    position: event.latLng,
    map: map,
    draggable: false,
    icon: icon
});

Ниже приведен рабочий пример того, как отображать и масштабировать значок SVG маркера:

JSFiddle демо

Edit:

Другой пример здесь со сложным значком:

JSFiddle демо

Изменить 2:

И вот как вы можете иметь SVG файл в качестве значка:

JSFiddle демо

Ответ 2

Если вам нужен полный svg не только путь, и вы хотите его модифицировать на стороне клиента (например, изменить текст, скрыть подробности,...), вы можете использовать альтернативный URL-адрес данных с включенным svg:

var svg = '<svg width="400" height="110"><rect width="300" height="100" /></svg>';
icon.url = 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg);

JavaScript (Firefox) btoa() используется для получения кодировки base64 из текста SVG. Вы также можете использовать http://dopiaza.org/tools/datauri/index.php для создания базовых URL-адресов.

Вот полный пример jsfiddle:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
        <script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
    </head>
    <body>
        <div id="map" style="width: 500px; height: 400px;"></div>
        <script type="text/javascript">
            var map = new google.maps.Map(document.getElementById('map'), {
                zoom: 10,
                center: new google.maps.LatLng(-33.92, 151.25),
                mapTypeId: google.maps.MapTypeId.ROADMAP
            });

            var template = [
                '<?xml version="1.0"?>',
                    '<svg width="26px" height="26px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg">',
                        '<circle stroke="#222" fill="{{ color }}" cx="50" cy="50" r="35"/>',
                    '</svg>'
                ].join('\n');
            var svg = template.replace('{{ color }}', '#800');

            var docMarker = new google.maps.Marker({
                position: new google.maps.LatLng(-33.92, 151.25),
                map: map,
                title: 'Dynamic SVG Marker',
                icon: { url: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg), scaledSize: new google.maps.Size(20, 20) },
optimized: false
            });

            var docMarker = new google.maps.Marker({
                position: new google.maps.LatLng(-33.95, 151.25),
                map: map,
                title: 'Dynamic SVG Marker',
                icon: { url: 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg), scaledSize: new google.maps.Size(20, 20) },
optimized: false
            });
        </script>
    </body>
</html>

Дополнительную информацию можно найти здесь.

Избегайте кодировки base64:

Чтобы избежать кодирования base64, вы можете заменить 'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg) на 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg)

Это должно работать с современными браузерами вплоть до IE9. Преимущество состоит в том, что encodeURIComponent является функцией js по умолчанию и доступна во всех современных браузерах. Вы также можете получить более мелкие ссылки, но вам нужно протестировать это и подумайте использовать ' вместо " в вашем svg.

Также см. Оптимизация SVG в URI данных для дополнительной информации.

Поддержка IE: Для поддержки SVG-маркеров в IE требуется две небольшие адаптации, описанные здесь: Маркеры SVG в IE. Я обновил код примера для поддержки IE.

Ответ 3

Я знаю, что этот пост немного устарел, но я видел так много плохой информации об этом в SO, чтобы я мог кричать. Поэтому я просто должен бросить свои два цента с совершенно другим подходом, который, как я знаю, работает, поскольку я надежно использовал его на многих картах. Кроме того, я считаю, что OP захотела также поворачивать маркер стрелки вокруг точки карты, что отличается от поворота значка вокруг собственной оси x, y, которая изменится там, где указатель стрелки указывает на карту.

Во-первых, помните, что мы играем с картами Google и SVG, поэтому мы должны соответствовать тому, как Google развертывает реализацию SVG для маркеров (или фактически символов). Google устанавливает привязку для изображения маркера SVG в 0,0, который НЕ является верхним левым углом SVG viewBox. Чтобы обойти это, вы должны нарисовать свой SVG-образ немного по-другому, чтобы дать Google то, что он хочет... да ответ в том, как вы на самом деле создаете путь SVG в редакторе SVG (Illustrator, Inkscape и т.д.)..).

Первый шаг - избавиться от viewBox. Это можно сделать, установив viewBox в вашем XML на 0... это правильно, всего один нуль вместо обычных четырех аргументов для viewBox. Это отключает окно просмотра (и да, это семантически правильно). Вероятно, вы заметите, что размер вашего изображения прыгает сразу же, когда вы это делаете, и это потому, что у svg больше нет базы (viewBox) для масштабирования изображения. Поэтому мы создаем эту ссылку напрямую, устанавливая ширину и высоту фактического количества пикселей, которые вы хотите, чтобы ваше изображение находилось в редакторе XML вашего редактора SVG.

Установив ширину и высоту изображения svg в редакторе XML, вы создаете базовую линию для масштабирования изображения, и по умолчанию этот размер становится значением 1 для свойств шкалы маркера. Вы можете увидеть преимущество, которое это имеет для динамического масштабирования маркера.

Теперь, когда у вас есть размер изображения, переместите изображение до тех пор, пока часть изображения, которое вы хотите иметь в качестве якоря, не будет находиться за 0,0 координатами редактора svg. После того, как вы сделали эту копию, значение атрибута d для пути svg. Вы заметите, около половины из числа отрицательна, что является результатом выравнивания вашей точки привязки для 0,0 изображений вместо Viewbox.

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

Я попытался сделать JSFiddle для этого, но есть некоторая ошибка в реализации, одна из причин, почему я не так увлекается переинтерпретированным кодом. Поэтому вместо этого я включил полностью автономный пример ниже, который вы можете попробовать, адаптировать и использовать в качестве ссылки. Это тот же код, который я пробовал в JSFiddle, который провалился, но он проплывает через Firebug без хныка.

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport"  content="width=device-width, initial-scale=1" />
    <meta name="author"    content="Drew G. Stimson, Sr. ( Epiphany )" />
    <title>Create Draggable and Rotatable SVG Marker</title>
    <script src="http://maps.googleapis.com/maps/api/js?sensor=false"> </script>
    <style type="text/css">
      #document_body {
        margin:0;
        border: 0;
        padding: 10px;
        font-family: Arial,sans-serif;
        font-size: 14px;
        font-weight: bold;
        color: #f0f9f9;
        text-align: center;
        text-shadow: 1px 1px 1px #000;
        background:#1f1f1f;
      }
      #map_canvas, #rotation_control {
        margin: 1px;
        border:1px solid #000;
        background:#444;
        -webkit-border-radius: 4px;
           -moz-border-radius: 4px;
                border-radius: 4px;
      }
      #map_canvas { 
        width: 100%;
        height: 360px;
      }
      #rotation_control { 
        width: auto;
        padding:5px;
      }
      #rotation_value { 
        margin: 1px;
        border:1px solid #999;
        width: 60px;
        padding:2px;
        font-weight: bold;
        color: #00cc00;
        text-align: center;
        background:#111;
        border-radius: 4px;
      }
</style>

<script type="text/javascript">
  var map, arrow_marker, arrow_options;
  var map_center = {lat:41.0, lng:-103.0};
  var arrow_icon = {
    path: 'M -1.1500216e-4,0 C 0.281648,0 0.547084,-0.13447 0.718801,-0.36481 l 17.093151,-22.89064 c 0.125766,-0.16746 0.188044,-0.36854 0.188044,-0.56899 0,-0.19797 -0.06107,-0.39532 -0.182601,-0.56215 -0.245484,-0.33555 -0.678404,-0.46068 -1.057513,-0.30629 l -11.318243,4.60303 0,-26.97635 C 5.441639,-47.58228 5.035926,-48 4.534681,-48 l -9.06959,0 c -0.501246,0 -0.906959,0.41772 -0.906959,0.9338 l 0,26.97635 -11.317637,-4.60303 c -0.379109,-0.15439 -0.812031,-0.0286 -1.057515,0.30629 -0.245483,0.33492 -0.244275,0.79809 0.0055,1.13114 L -0.718973,-0.36481 C -0.547255,-0.13509 -0.281818,0 -5.7002158e-5,0 Z',
    strokeColor: 'black',
    strokeOpacity: 1,
    strokeWeight: 1,
    fillColor: '#fefe99',
    fillOpacity: 1,
    rotation: 0,
    scale: 1.0
  };

function init(){
  map = new google.maps.Map(document.getElementById('map_canvas'), {
    center: map_center,
    zoom: 4,
    mapTypeId: google.maps.MapTypeId.HYBRID
  });
  arrow_options = {
    position: map_center,
    icon: arrow_icon,
    clickable: false,
    draggable: true,
    crossOnDrag: true,
    visible: true,
    animation: 0,
    title: 'I am a Draggable-Rotatable Marker!' 
  };
  arrow_marker = new google.maps.Marker(arrow_options);
  arrow_marker.setMap(map);
}
function setRotation(){
  var heading = parseInt(document.getElementById('rotation_value').value);
  if (isNaN(heading)) heading = 0;
  if (heading < 0) heading = 359;
  if (heading > 359) heading = 0;
  arrow_icon.rotation = heading;
  arrow_marker.setOptions({icon:arrow_icon});
  document.getElementById('rotation_value').value = heading;
}
</script>
</head>
<body id="document_body" onload="init();">
  <div id="rotation_control">
    <small>Enter heading to rotate marker&nbsp;&nbsp;&nbsp;&nbsp;</small>
    Heading&deg;<input id="rotation_value" type="number" size="3" value="0" onchange="setRotation();" />
    <small>&nbsp;&nbsp;&nbsp;&nbsp;Drag marker to place marker</small>
    </div>
    <div id="map_canvas"></div>
</body>
</html>

Это именно то, что Google делает для своих собственных символов, доступных в классе SYMBOL API Карт, поэтому, если это вас не убедит... Во всяком случае, я надеюсь, что это поможет вам правильно составить и настроить SVG-маркер для ваших сторонних карт Google.

Ответ 4

Да, вы можете использовать файл .svg для значка так же, как вы можете .png или другой формат файла изображения. Просто установите URL-адрес значка в каталог, в котором находится файл .svg. Например:

var icon = {
        url: 'path/to/images/car.svg',
        size: new google.maps.Size(sizeX, sizeY),
        origin: new google.maps.Point(0, 0),
        anchor: new google.maps.Point(sizeX/2, sizeY/2)
};

var marker = new google.maps.Marker({
        position: event.latLng,
        map: map,
        draggable: false,
        icon: icon
});

Ответ 5

Дела идут лучше, прямо сейчас вы можете использовать SVG файлы.

        marker = new google.maps.Marker({
            position: {lat: 36.720426, lng: -4.412573},
            map: map,
            draggable: true,
            icon: "img/tree.svg"
        });

Ответ 6

OK! Я сделал это скоро в своей сети, я пробую два способа создания пользовательского маркера карты google, этот код запуска использует canvg.js - лучшая совместимость для браузера. Код комментария не поддерживает IE11 в настоящее время.

var marker;
var CustomShapeCoords = [16, 1.14, 21, 2.1, 25, 4.2, 28, 7.4, 30, 11.3, 30.6, 15.74, 25.85, 26.49, 21.02, 31.89, 15.92, 43.86, 10.92, 31.89, 5.9, 26.26, 1.4, 15.74, 2.1, 11.3, 4, 7.4, 7.1, 4.2, 11, 2.1, 16, 1.14];

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 13,
    center: {
      lat: 59.325,
      lng: 18.070
    }
  });
  var markerOption = {
    latitude: 59.327,
    longitude: 18.067,
    color: "#" + "000",
    text: "ha"
  };
  marker = createMarker(markerOption);
  marker.setMap(map);
  marker.addListener('click', changeColorAndText);
};

function changeColorAndText() {
  var iconTmpObj = createSvgIcon( "#c00", "ok" );
  marker.setOptions( {
                icon: iconTmpObj
            } );
};

function createMarker(options) {
  //IE MarkerShape has problem
  var markerObj = new google.maps.Marker({
    icon: createSvgIcon(options.color, options.text),
    position: {
      lat: parseFloat(options.latitude),
      lng: parseFloat(options.longitude)
    },
    draggable: false,
    visible: true,
    zIndex: 10,
    shape: {
      coords: CustomShapeCoords,
      type: 'poly'
    }
  });

  return markerObj;
};

function createSvgIcon(color, text) {
  var div = $("<div></div>");

  var svg = $(
    '<svg width="32px" height="43px"  viewBox="0 0 32 43" xmlns="http://www.w3.org/2000/svg">' +
    '<path style="fill:#FFFFFF;stroke:#020202;stroke-width:1;stroke-miterlimit:10;" d="M30.6,15.737c0-8.075-6.55-14.6-14.6-14.6c-8.075,0-14.601,6.55-14.601,14.6c0,4.149,1.726,7.875,4.5,10.524c1.8,1.801,4.175,4.301,5.025,5.625c1.75,2.726,5,11.976,5,11.976s3.325-9.25,5.1-11.976c0.825-1.274,3.05-3.6,4.825-5.399C28.774,23.813,30.6,20.012,30.6,15.737z"/>' +
    '<circle style="fill:' + color + ';" cx="16" cy="16" r="11"/>' +
    '<text x="16" y="20" text-anchor="middle" style="font-size:10px;fill:#FFFFFF;">' + text + '</text>' +
    '</svg>'
  );
  div.append(svg);

  var dd = $("<canvas height='50px' width='50px'></cancas>");

  var svgHtml = div[0].innerHTML;

  canvg(dd[0], svgHtml);

  var imgSrc = dd[0].toDataURL("image/png");
  //"scaledSize" and "optimized: false" together seems did the tricky ---IE11  &&  viewBox influent IE scaledSize
  //var svg = '<svg width="32px" height="43px"  viewBox="0 0 32 43" xmlns="http://www.w3.org/2000/svg">'
  //    + '<path style="fill:#FFFFFF;stroke:#020202;stroke-width:1;stroke-miterlimit:10;" d="M30.6,15.737c0-8.075-6.55-14.6-14.6-14.6c-8.075,0-14.601,6.55-14.601,14.6c0,4.149,1.726,7.875,4.5,10.524c1.8,1.801,4.175,4.301,5.025,5.625c1.75,2.726,5,11.976,5,11.976s3.325-9.25,5.1-11.976c0.825-1.274,3.05-3.6,4.825-5.399C28.774,23.813,30.6,20.012,30.6,15.737z"/>'
  //    + '<circle style="fill:' + color + ';" cx="16" cy="16" r="11"/>'
  //    + '<text x="16" y="20" text-anchor="middle" style="font-size:10px;fill:#FFFFFF;">' + text + '</text>'
  //    + '</svg>';
  //var imgSrc = 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);

  var iconObj = {
    size: new google.maps.Size(32, 43),
    url: imgSrc,
    scaledSize: new google.maps.Size(32, 43)
  };

  return iconObj;
};
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>Your Custom Marker </title>
  <style>
    /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
    #map {
      height: 100%;
    }
    /* Optional: Makes the sample page fill the window. */
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
</head>

<body>
  <div id="map"></div>
    <script src="https://canvg.github.io/canvg/canvg.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
</body>

</html>

Ответ 7

Как упоминалось другими в этом потоке, не забудьте явно установить атрибуты width и height в svg, например:

<svg id="some_id" data-name="some_name" xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 26 42"
     width="26px" height="42px">

если вы не делаете этого, никакая манипуляция js не может помочь вам, поскольку gmaps не будут иметь систему отсчета и всегда будут использовать стандартный размер.

(я знаю, что это было упомянуто в некоторых комментариях, но их легко пропустить. Эта информация помогла мне в разных случаях)

Ответ 8

Вам нужно пройти optimized: false.

например.

var img = { url: 'img/puff.svg', scaledSide: new google.maps.Size(5, 5) };
new google.maps.Marker({position: this.mapOptions.center, map: this.map, icon: img, optimized: false,});

Без передачи optimized: false мой svg появился как статическое изображение.