在Google地图V3上旋转图片/标记图片

如何在Google地图V3上旋转图像(标记图像)?

  • 这里有一个很好的例子,正是我所需要的。 但对于GMap2! 他们用旋转的canvas来做。
  • 用JS / JQuery旋转的图像经常被使用,关于这个有很多答案 。 但是,我怎么能把这个应用到我的地图图像?
  • 一个提到的方法是在不同的angular度有不同的图像,并在其中切换 – 这不是我想要的。 我不喜欢有这么多的图片,我想通过代码旋转。

备注:有类似的问题,但所有的V2和V3(据我所知)。 我需要V3。

我用下面的代码在v3中完成了旋转:

<canvas id="carcanvas" width="1" height="1"></canvas> if (document.getElementById('carcanvas').getContext) { var supportsCanvas = true; } else { var supportsCanvas = false; } var rImg = new Image(); rImg.src='http://img.dovov.comcariconl.png'; // Returns the bearing in radians between two points. function bearing( from, to ) { // Convert to radians. var lat1 = from.latRadians(); var lon1 = from.lngRadians(); var lat2 = to.latRadians(); var lon2 = to.lngRadians(); // Compute the angle. var angle = - Math.atan2( Math.sin( lon1 - lon2 ) * Math.cos( lat2 ), Math.cos( lat1 ) * Math.sin( lat2 ) - Math.sin( lat1 ) * Math.cos( lat2 ) * Math.cos( lon1 - lon2 ) ); if ( angle < 0.0 ) angle += Math.PI * 2.0; if (angle == 0) {angle=1.5;} return angle; } function plotcar() { canvas = document.getElementById("carcanvas").getContext('2d'); var cosa = Math.cos(angle); var sina = Math.sin(angle); canvas.clearRect(0,0,32,32); canvas.save(); canvas.rotate(angle); canvas.translate(16*sina+16*cosa,16*cosa-16*sina); canvas.drawImage(rImg,-16,-16); canvas.restore(); } 

并在animation方法中:

 if (supportsCanvas) { angle = bearing(new google.maps.LatLng(lat1, lng1),new google.maps.LatLng(lat2, lng2)); plotcar(); } 

我希望有所帮助。

我的js类解决这个问题是:

 var RotateIcon = function(options){ this.options = options || {}; this.rImg = options.img || new Image(); this.rImg.src = this.rImg.src || this.options.url || ''; this.options.width = this.options.width || this.rImg.width || 52; this.options.height = this.options.height || this.rImg.height || 60; var canvas = document.createElement("canvas"); canvas.width = this.options.width; canvas.height = this.options.height; this.context = canvas.getContext("2d"); this.canvas = canvas; }; RotateIcon.makeIcon = function(url) { return new RotateIcon({url: url}); }; RotateIcon.prototype.setRotation = function(options){ var canvas = this.context, angle = options.deg ? options.deg * Math.PI / 180: options.rad, centerX = this.options.width/2, centerY = this.options.height/2; canvas.clearRect(0, 0, this.options.width, this.options.height); canvas.save(); canvas.translate(centerX, centerY); canvas.rotate(angle); canvas.translate(-centerX, -centerY); canvas.drawImage(this.rImg, 0, 0); canvas.restore(); return this; }; RotateIcon.prototype.getUrl = function(){ return this.canvas.toDataURL('image/png'); }; 

像这样调用它:

 var marker = new google.maps.Marker({ icon: { url: RotateIcon .makeIcon( 'https://ru.gravatar.com/userimage/54712272/b8eb5f2d540a606f4a6c07c238a0bf40.png') .setRotation({deg: 92}) .getUrl() }}) 

在这里看到生动的例子http://jsfiddle.net/fe9grwdf/39/

我发现了两个对Google MAP V3的扩展: infobox.js和markerwithlabel.js都可以处理一个图像DOM元素作为内容,这反过来我可以通过jQuery 图像旋转插件进行旋转 。

这甚至可以在旋转后不再设置标记图像的情况下工作。

编辑:至于下面的问题/评论:

标签的扩展是必需的,因为它可以处理其他的DOM元素。 所以我可以添加任意的HTML作为标签,在我的情况下,我添加图像。 然后我旋转这个图像(标签的孩子)与旋转插件。 因此,分配图像的ID为了方便地访问它。 实际上,我只是为图片使用了一个标签,而另一个则用于描述性文字。

编辑2:由于斯蒂芬对DOM就绪的评论

在我的代码中,我发现了以下几行。 这表明我在旋转图像之前在标签上强制绘图。

  if (!this._drawn) myImageLabel.draw(); // 1st time force a draw, otherwise rotating the image will fail because an asynchronously drawn object has not all tags in place if (this.heading != 0) this.rotateImage(this.heading, true); 

编辑3:代码示例如何创buildInfobox.js

 this._img = document.createElement('img'); ... further manipulations of _img / Size / Id / ... var planeImageLabelOptions = { content: this._img, disableAutoPan: true, boxStyle: planeImageLabelBoxStyle, pixelOffset: new google.maps.Size(-imgOffsetW / 2, -imgOffsetH / 2), closeBoxURL: "", position: latlng, zIndex: this.altitude < 0 ? 100 : this.altitude }; var planeImageLabel = new InfoBox(planeImageLabelOptions); 

我也很难找出旋转.png标记的方法。 我像下面解决它。 您可以使用相同的自定义图像创build多个标记并旋转要旋转的特定标记。 我希望对你有帮助。

 var id = 'my_marker_01'; var img_url = "../img/car.png"; var my_icon = img_url + "#" + id; var marker = new google.maps.Marker({ icon: my_icon, ... }); var rotate = 45; $(`img[src="${my_icon}"]`).css( {'-webkit-transform' : 'rotate('+ rotate +'deg)', '-moz-transform' : 'rotate('+ rotate +'deg)', '-ms-transform' : 'rotate('+ rotate +'deg)', 'transform' : 'rotate('+ rotate +'deg)'}); 

你没有在你的问题中说明,但我假设你想要这个旋转相对于点a和点b之间的一条线,这将是他们的path。 为了制作一个可以旋转的Google svg图标,您需要使用google符号类对象来定义标记符号的属性。 这不使用完整的.svg文件,而只使用path的d属性。 请注意,Google符号类每个标记只能采用一个path。

颜色,笔画,宽度,不透明度等的其他属性可以在使用javascript(直接更新标记对象属性)或使用CSS(通过添加和删除类来更新标记属性)创build标记之后设置。

举个例子,下面将创build一个可以拖动的箭头标记,它将围绕地图上的标记进行旋转,该标记即使在标记被移动后也是纬度和长度。

HTML

 <body id="document_body" onload="init();"> <div id="rotation_control"> Heading&deg;<input id="rotation_value" type="number" size="3" value="0" onchange="setRotation();" /> </div> <div id="map_canvas"></div> </body> 

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

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

而最好的方式是这样做,确保标记是一个Google MVC对象,为它提供了MVC对象提供的所有附加方法。

如果您必须将多种颜色的图像作为您的标记,然后创build一个.png精灵表,并以所有希望显示的angular度显示图像,然后根据计算的方位select正确的图像在你使用的两点之间。 但是,这不是一个SVG图像,而是一个普通的标记图像。

希望这有助于做出有关地图标记的决定。

如何在Google地图V3上旋转图像(标记图像)?

我有同样的问题,我解决了下一个代码:

 var gmap; NgMap.getMap(function(map){ gmap = map; }); 

我想你有一个图标的variables,例如:

 var imagePath = 'img/customMarker.png'; 

首先,我们需要创build我们的标记选项:

 var markerOptions = { location: [x, y], title:'some text', draggable: true, . . . icon: imagePath }; 

我们来创build一个标记:

 var marker = new google.maps.Marker(markerOptions); 

我们必须设置地图:

 marker.setMap(map); 

现在,如果你想旋转图像,你需要下一个:

  • 将imagePathvariables的值更改为“img / customMarker.png#yourId”
  • 用CSS设置旋转值(例如使用JQuery)

让我们来看看

 imagePath = 'img/customMarker.png#markerOne'; $('img[src="img/customMarker.png#markerOne"]').css({ 'transform': 'rotate(45deg)' }); 

当然,你可以做更多的花式:

 function rotateMarker(selector, degree){ $('img[src="img/customMarker.png#'+selector+'"]').css({ 'transform': 'rotate('+degree+'deg)' }); } 

而你的电话:

 rotateMarker('markerOne', 45); 

就这样。

我为我可怜的英语感到抱歉。 我希望这可能是有希望的。

我能够很容易地解决这个问题,但是使用指向使用svgpath语法的自定义符号的marker.icon.rotation选项。

 $scope.triangle = { path: 'M 0 0 L -35 -100 L 35 -100 z', fillColor: '#3884ff', fillOpacity: 0.7, scale: 1, strokeColor: '#356cde', rotation: 90, strokeWeight: 1 }; 

如果使用angular度谷歌地图,绑定一个UI控件来改变triangle.rotation是微不足道的。

就像我用这个滑块做的一样。

 <slider ng-model="triangle.rotation" floor="0" ceiling="359" step="5" precsion="1"></slider> 

但你也可以使用论坛。

这里是我的plunker http://plnkr.co/edit/x0egXI

每次图像更改时,您都可以调用yourmarker.setIcon(canvas.toDataUrlOrSomeThig)。 我没有看到任何直接使用canvas元素的API参考,除非你实现你自己的google.maps.OverlayView。

如果你只想animation,你可以使用一个GIF,并添加优化标记选项:false。

最简单的方法可能是使用google.maps.Symbol的旋转属性 。 创build或更新标记时,只需将其设置为图标的属性即可:

 new google.maps.Marker({ position: map.getCenter(), icon: { path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW, scale: 7, rotation: 193 }, map: map }); 

Plunker

这是我如何实现我的形象旋转,我认为在覆盖的forms标记和覆盖位置的位置,下面的代码将被添加。

没有使用任何额外的图书馆,它是旋转,你需要解决scheme添加点击事件和鼠标事件的叠加,不类似标记点击事件。

随着谷歌地图标记自定义,地图上将有额外的内存使用量。 这也将减less地图中自定义标记的内存消耗。

  <html> <head> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <style>html, body { height: 100%; margin: 0; padding: 0; } #map_canvas { height: 100%; } div.htmlMarker { color: red; cursor: pointer; } </style> </head> <body onload="initialize()"> <div id="map_canvas"></div> </body> <script> var overlay; function initialize() { var myLatLng = new google.maps.LatLng(40, -100); var mapOptions = { zoom: 10, center: myLatLng, mapTypeId: google.maps.MapTypeId.ROADMAP }; var gmap = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); function HTMLMarker(lat, lng, rotation) { this.lat = lat; this.lng = lng; this.rotation = rotation; this.pos = new google.maps.LatLng(lat, lng); } HTMLMarker.prototype = new google.maps.OverlayView(); HTMLMarker.prototype.onRemove = function () {} //Initilize your html element here HTMLMarker.prototype.onAdd = function () { div = document.createElement('DIV'); div.style.position='absolute'; div.style.transform='rotate('+this.rotation +'deg)'; div.style.MozTransform='rotate('+this.rotation +'deg)'; div.className = "htmlMarker"; //image source use your own image in src div.innerHTML = '<img src="prudvi.png" alt="Mountain View" style="width:25px;height:22px">' ; var panes = this.getPanes(); panes.overlayImage.appendChild(div); this.div=div; } HTMLMarker.prototype.draw = function () { var overlayProjection = this.getProjection(); var position = overlayProjection.fromLatLngToDivPixel(this.pos); var panes = this.getPanes(); this.div.style.left = position.x + 'px'; this.div.style.top = position.y - 30 + 'px'; } //Added 50 marker with random latlng location and random rotation, for (i = 0; i < 50; i++) { var PoslatLng = new google.maps.LatLng(myLatLng.lat() + Math.random() - 0.5, myLatLng.lng() + Math.random() - 0.5); var htmlMarker = new HTMLMarker(myLatLng.lat() + Math.random() - 0.5,myLatLng.lng() + Math.random() - 0.5, Math.floor(Math.random() * 359)); htmlMarker.setMap(gmap); google.maps.event.addListener(htmlMarker, 'click', function() { console.log('clciked') gmap.setZoom(8); gmap.setCenter(htmlMarker.getPosition()); }); } } </script> </html> 

使用MarkerWithLabel库,你可以这样做:

 var ico = document.createElement('img'); ico.src = 'ImageSource'; ico.setAttribute('style', 'transform:rotate('30deg);'); mapMarkers[0].labelContent = ico; mapMarkers[0].label.draw(); 

这个想法是首先在隐藏的canvas上绘制旋转的标记图像。

说,你有一个隐藏的canvas:

<canvas id="carCanvas" width="50" height="50" style="display:none"></canvas>

现在你可以做到这一点:

 function updateCarMarker(i,lat, lng, icon = "img/carIcon.png") { var latLong = new google.maps.LatLng(lat, lng); if (!carMarkers[i]){ var carImage = new Image(); carImage.onload = ()=>{ drawMovedCar(i,latLong,carImage); } carImage.src=icon; } else { drawMovedCar(i,latLong,carMarkers[i].carImage); } } function drawMovedCar(i,latLong,I){ let m=carMarkers[i]; let canvas = document.getElementById("carCanvas"); let C = canvas.getContext('2d'); if (m){ var distance = google.maps.geometry.spherical.computeDistanceBetween( m.getPosition(), latLong); var deg = (distance<2)?carMarkers[i].deg :google.maps.geometry.spherical.computeHeading(m, latLong); carMarkers[i].setMap(null); } else { var deg=0; } C.save(); C.clearRect(0, 0, canvas.width, canvas.height); C.translate(canvas.width/2,canvas.height/2); C.rotate(deg * Math.PI / 180); C.scale(0.4,0.4); C.drawImage(I,-I.width/2,-I.height/2,I.width,I.height); C.restore(); if (!m){ m = new google.maps.Marker({ position: latLong, map: map, icon: canvas.toDataURL("image/png",1) }); m.deg = deg; m.carImage = I; carMarkers[i]=m; } else { m.setIcon(canvas.toDataURL("image/png",1)); m.setPosition(latLong); } } 

以上是我的原始代码。 我已经完好无损,以便您可以看到我的其他优化。

 var icon = { path: aeroplanePath/image, fillColor: '#0000FF', fillOpacity: .6, anchor: new google.maps.Point(0,0), strokeWeight: 0, scale: 1, rotation: 180 } var marker = new google.maps.Marker({ position: positions[k], icon: icon, draggable: true, title: "BOING-707", });