如何在Google Maps API v3中使用SVG标记
我可以使用我的转换image.svg作为谷歌地图icon.I转换我的PNG图像为SVG,我想使用这个像谷歌地图符号,可以rotate.I已经尝试使用谷歌地图符号,但我想有像汽车,男人等图标…这就是为什么我把我的一些PNG文件转换为SVG。 就像这个例子网站,他用这些http://www.goprotravelling.com/
您可以使用SVGpath表示法呈现您的图标。
有关更多信息,请参阅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演示
编辑:
这里有一个复杂图标的另一个例子:
JSFiddle演示
编辑2:
下面是如何将SVG文件作为图标:
JSFiddle演示
如果你需要一个完整的svg不仅是一个path,而且你希望它在客户端可以修改(例如改变文本,隐藏详细信息,…),你可以使用一个替代的数据“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()用于从SVG文本中获取base64编码。 您也可以使用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>
其他信息可以在这里find。
避免base64编码:
为了避免base64编码,你可以用'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg)
replace'data:image/svg+xml;charset=UTF-8;base64,' + btoa(svg)
'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg)
这应该与现代浏览器一起工作到IE9。 其优点是encodeURIComponent
是一个默认的js函数,并可在所有现代浏览器中使用。 你也可能会得到更小的链接,但你需要testing这个,并考虑在你的svg中使用'
而不是"
。
另请参阅优化数据URI中的SVG以获取更多信息。
IE支持:为了支持IE中的SVG标记,需要两个小的适配,如下所述: IE中的SVG标记 。 我更新了示例代码来支持IE。
我知道这个post有点旧了,但是我在SO上看到了很多关于这个消息的不好的信息,所以我可以尖叫。 所以我只需要用我完全不同的方法来投入我的两分钱,因为我可以在许多地图上可靠地使用它。 除此之外,我相信OP还希望能够在地图点周围旋转箭头标记,这与绕自己的x,y轴旋转图标不同,它将改变地图上箭头标记指向的位置。
首先,请记住我们正在使用Google地图和SVG,所以我们必须适应Google部署SVG实现标记(或实际符号)的方式。 Google将其SVG标记图像的锚点设置为0,0,这不是SVG viewBox的左上angular。 为了解决这个问题,你必须绘制你的SVG图像有点不同,给了它想要的东西…是的答案是在你的SVG编辑器(Illustrator,Inkscape等)中实际创buildSVGpath的方式。 )。
第一步,就是摆脱viewBox。 这可以通过将您的XML中的viewBox设置为0来完成……这是正确的,只是一个零而不是viewBox的四个参数。 这将closures视图框(是的,这是在语义上是正确的)。 当你这样做的时候,你可能会注意到图像的大小跳跃,那是因为svg不再有一个基础(viewBox)来缩放图像。 所以我们直接创build这个引用,将宽度和高度设置为希望图像在SVG编辑器的XML编辑器中的实际像素数。
通过在XML编辑器中设置svg图像的宽度和高度,您可以创build图像缩放的基准,默认情况下,此大小对于标记缩放属性的值为1。 您可以看到这个标记的dynamic缩放的优势。
现在你的图像大小了,移动图像直到图像中你希望作为锚点的部分超过svg编辑器的0,0坐标。 一旦你完成了这个复制svgpath的d属性的值。 你会注意到大约一半的数字是负数,这是alignment图像的0,0而不是viewBox的定位点的结果。
然后使用这种技术,可以让您在地图上的lat和lng点周围正确旋转标记。 这是唯一可靠的方法来绑定你想要的标志位置的纬度和长度的SVG标记点。
我试图为此做一个JSFiddle ,但是在那里实现了一些bug,我不喜欢重新解释代码的原因之一。 相反,我在下面包含了一个完全独立的示例,您可以尝试,适应并将其用作参考。 这是我在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 </small> Heading°<input id="rotation_value" type="number" size="3" value="0" onchange="setRotation();" /> <small> Drag marker to place marker</small> </div> <div id="map_canvas"></div> </body> </html>
这正是Google为Google地图API的SYMBOL类中提供的几个符号所做的,所以如果这不能说服您的话……无论如何,我希望这会帮助您正确地创build和设置一个SVG标记你的谷歌地图的努力。
是的,你可以使用一个.svg文件的图标就像你可以.png或其他图像文件格式。 只需将图标的url设置为.svg文件所在的目录即可。 例如:
var icon = { url: 'path/tohttp://img.dovov.comcar.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 });
事情正在好转,现在你可以使用SVG文件。
marker = new google.maps.Marker({ position: {lat: 36.720426, lng: -4.412573}, map: map, draggable: true, icon: "img/tree.svg" });
好! 我很快在我的网页上做了这个,我尝试了两种方法来创build自定义的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>
正如本文中其他人所提到的,不要忘记在svg中显式设置width和height属性,如下所示:
<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不会有一个参考框架,并始终使用标准尺寸。
(我知道在一些评论中已经提到过,但是很容易错过,这些信息在不同的情况下帮了我的忙)
你需要通过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
,我的SVGperformance为静态图像。