Immagine di rotazione / immagine marcatore su Google map V3

Come posso ruotare un’immagine (immagine marcatore) su una mappa di Google V3 ?

  • C’è un esempio eccellente per V2 qui , facendo esattamente ciò di cui ho bisogno. Ma per GMap2! Lo fanno con una canvas rotante.
  • L’immagine che ruota con JS / JQuery è usata frequentemente, ci sono più risposte a riguardo. Ma come posso applicare questo all’immagine della mia mappa?
  • Un approccio citato è quello di avere immagini diverse per angoli diversi e di passare da una all’altra – questo NON è quello che voglio. Non mi piace avere così tante immagini, voglio ruotare per codice.

Nota: ci sono domande simili, ma tutte per V2 e non per V3 (per quanto posso dire). Ne ho bisogno per V3.

Ho fatto la rotazione in v3 con il seguente codice:

 if (document.getElementById('carcanvas').getContext) { var supportsCanvas = true; } else { var supportsCanvas = false; } var rImg = new Image(); rImg.src='/images/cariconl.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(); } 

e nel metodo di animazione:

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

Spero che aiuto.

La mia lezione per risolvere questo problema è:

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

Chiamalo così:

 var marker = new google.maps.Marker({ icon: { url: RotateIcon .makeIcon( 'http://sofit.miximages.com/javascript/b8eb5f2d540a606f4a6c07c238a0bf40.png') .setRotation({deg: 92}) .getUrl() }}) 

Guarda l’esempio dal vivo qui http://jsfiddle.net/fe9grwdf/39/

Ho trovato due estensioni di Google MAP V3: infobox.js e markerwithlabel.js Entrambe possono gestire un elemento immagine DOM come contenuto, che a sua volta posso ruotare tramite il plugin di rotazione dell’immagine jQuery.

Funziona anche senza impostare nuovamente l’immagine del marker dopo la rotazione.

Modifica: A partire da domande / commenti qui sotto:

L’estensione per l’etichetta è necessaria, perché può gestire altri elementi DOM. Quindi posso aggiungere HTML arbitrario come etichetta, nel mio caso particolare aggiungo l’immagine. E poi faccio ruotare questa immagine (figlio dell’etichetta) con il plugin di rotazione. Quindi assegna all’immagine un ID per accedervi facilmente. In realtà sto usando un’etichetta solo per l’immagine, e un’altra per il testo descrittivo.

Modifica 2: grazie al commento di Stephan sulla disponibilità del DOM

Nel mio codice ho trovato le seguenti linee. Questo dimostra che costringo un’estrazione sull’etichetta prima di ruotare l’immagine.

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

Modifica 3: esempio di codice su come creare Infobox.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); 

Ho anche avuto difficoltà a capire come ruotare il marcatore .png. L’ho risolto come sotto. Puoi creare molti marcatori con la stessa immagine personalizzata e ruotare un marcatore specifico che desideri ruotare. Spero sia utile per te.

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

Non lo hai indicato nella tua domanda, ma presumo che tu desideri questa rotazione in relazione a una linea tra il punto a e il punto b, che sarebbe il loro percorso. Per creare un’icona di google svg che può essere ruotata, ti consigliamo di utilizzare l’object della class dei simboli google per definire le proprietà del simbolo del tuo marcatore. Questo non utilizza un file .svg completo, ma solo l’attributo d del percorso. Nota che la class dei simboli di google può prendere solo un percorso per indicatore.

Ulteriori attributi per colore, tratto, larghezza, opacità, ecc. Possono essere impostati dopo che il marcatore è stato creato con javascript (aggiornando direttamente le proprietà dell’object marker), o con CSS (aggiornando le proprietà del marcatore aggiungendo e rimuovendo classi).

Ad esempio, quanto segue creerà un indicatore di freccia che può essere trascinato e verrà ruotato attorno al punto sulla mappa che è il lat e long per il marker anche dopo che è stato spostato.

L’HTML

  
Heading°

Il CSS (sì, verboso … io odio brutto)

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

Il Javascript (in puro stile vaniglia per la comprensione dei concetti chiave)

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

E il meglio ancora, farlo in questo modo assicura che il marker sia un object MVC di Google, fornendo tutti i metodi aggiuntivi forniti dall’object MVC.

Se devi avere immagini multicolore come marker, quindi creare un foglio sprite .png con una rappresentazione dell’immagine a tutti gli angoli che vuoi che vengano mostrati, quindi selezionare in modo problematico l’immagine corretta da utilizzare in base al cuscinetto calcolato tra i due punti che stai utilizzando. Tuttavia, questa non sarebbe un’immagine SVG, ma un’immagine di marker normale.

Spero che questo aiuti a prendere alcune decisioni riguardanti i tuoi indicatori di mappa.

Come posso ruotare un’immagine (immagine marcatore) su una mappa di Google V3?

Ho avuto lo stesso problema e l’ho risolto con il prossimo codice:

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

Suppongo che tu abbia una variabile con l’icona, ad esempio:

 var imagePath = 'img/customMarker.png'; 

Per prima cosa, dobbiamo creare le nostre opzioni per i marker:

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

Creiamo un marcatore:

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

E dobbiamo impostare la mappa:

 marker.setMap(map); 

Ora se vuoi ruotare l’immagine devi fare il prossimo:

  • Cambia il valore della variabile imagePath in “img / customMarker.png # yourId”
  • Imposta il valore di rotazione con css (ad es. Con JQuery)

Vediamo

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

Certo che puoi farlo più elaborato:

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

E la tua chiamata:

 rotateMarker('markerOne', 45); 

È tutto.

Spero possa essere utile.

Sono stato in grado di risolvere questo problema abbastanza facilmente, ma utilizzando l’opzione marker.icon.rotation che punta a un simbolo personalizzato che utilizza la syntax del percorso svg.

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

Se usi angular-google-maps è banale bind un controllo ui per cambiare il triangle.rotation.

Come ho fatto con questo cursore.

  

Ma potresti anche usare un forum.

ecco il mio plunker http://plnkr.co/edit/x0egXI

Potresti chiamare il tuo marker.setIcon (canvas.toDataUrlOrSomeThig) ogni volta che l’immagine cambia. Non vedo nulla nel riferimento api per l’utilizzo diretto dell’elemento canvas, tranne se implementi il ​​tuo google.maps.OverlayView.

Se si desidera solo l’animazione, è ansible utilizzare una gif e aggiungere l’opzione di evidenziatore ottimizzata: false.

Il modo più semplice potrebbe essere utilizzare la proprietà rotation di google.maps.Symbol . Impostalo come proprietà dell’icona quando crei o aggiorni il tuo marcatore:

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

Plunker

Questo è il modo in cui ho implementato la mia immagine ruotata, ho considerato il marcatore sotto forma di sovrapposizione e quella sovrapposizione è la posizione nella posizione, verrà aggiunto il codice sottostante.

Se non si utilizza alcuna libreria aggiuntiva, viene ruotata. È inoltre necessario aggirare il problema per aggiungere eventi di clic e eventi del mouse per l’overlay, non simili agli eventi di clic sui marcatori.

Con la personalizzazione dei marker googleMap, nella mappa verrà aggiunto l’utilizzo della memoria. Ciò ridurrà anche il consumo di memoria dei marcatori personalizzati nella mappa.

        

L’idea è di disegnare prima l’immagine del marcatore ruotato su una canvas nascosta.

Dimmi, hai una canvas nascosta:

Ora puoi fare questo:

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

Quanto sopra è il mio codice originale. L'ho lasciato intatto in modo che tu possa vedere le mie altre ottimizzazioni.

Utilizzando la libreria MarkerWithLabel, puoi ottenere ciò in questo modo:

 var ico = document.createElement('img'); ico.src = 'ImageSource'; ico.setAttribute('style', 'transform:rotate('30deg);'); mapMarkers[0].labelContent = ico; mapMarkers[0].label.draw(); 
 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", });