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

Поворот изображения/изображения на карте Google V3

Как я могу повернуть изображение (изображение маркера) на карте Google V3?

  • Существует отличный пример для V2 здесь, и именно то, что мне нужно. Но для GMap2! Они делают это с вращающимся холстом.
  • Часто используется поворот изображения с помощью JS/JQuery, есть несколько ответов об этом. Но как я могу применить это к моему изображению карт?
  • Один упомянутый подход заключается в том, чтобы иметь разные изображения для разных углов и переключаться между ними - это НЕ то, что я хочу. Мне не нравится иметь так много изображений, я хочу повернуть по коду.

Примечание. Есть похожие вопросы, но все для V2, а не V3 (насколько я могу судить). Мне нужно это для V3.

4b9b3361

Ответ 1

Я сделал поворот в 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='/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();
    }

и в методе анимации:

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

Я надеюсь, что помощь.

Ответ 2

Мой класс 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/

Ответ 3

Я нашел два расширения для Google MAP V3: infobox.js и markerwithlabel.js Оба могут обрабатывать элемент DOM изображения как контент, который в свою очередь я могу вращать с помощью плагина jQuery .

Это даже работает без установки изображения маркера снова после вращения.

Изменить: По вопросам/комментариям ниже:

Требуется расширение для метки, поскольку оно может обрабатывать другие элементы DOM. Поэтому я могу добавить произвольный HTML как метку, в моем конкретном случае я добавляю изображение. И затем я поворачиваю это изображение (дочерний элемент метки) с помощью плагина rotate. Поэтому присвойте образ идентификатору, чтобы легко получить к нему доступ. На самом деле я использую один ярлык только для изображения, а другой для описательного текста.

Редактировать 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: Пример кода, как создать 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);

Ответ 4

Мне также нелегко было выяснить способ поворота маркера .png. Я решил это, как показано ниже. Вы можете создать много маркеров с одинаковым пользовательским изображением и поверните определенный маркер, который вы хотите повернуть. Надеюсь, вам это поможет.

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

Ответ 5

Вы не указали это в своем вопросе, но я предполагаю, что вы хотите этот поворот относительно линии между точкой a и точкой b, которая будет их путем. Чтобы сделать значок Google svg, который можно повернуть, вам нужно будет использовать объект класса символа google для определения свойств вашего символа маркера. Это не использует полный .svg файл, а только атрибут d пути. Обратите внимание, что класс символов google может принимать только один путь на маркер.

Дополнительные атрибуты для цвета, штриха, ширины, непрозрачности и т.д. могут быть заданы после создания маркера с помощью javascript (обновление свойств объекта маркера напрямую) или с помощью CSS (обновление свойств маркера путем добавления и удаления классов).

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

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

И самое лучшее, сделав это таким образом, этот маркер является объектом MVC Google, предоставляя ему все дополнительные методы, предоставляемые объектом MVC.

Если у вас должны быть разноцветные изображения в качестве маркера, создайте лист спрайтов .png с исполнением изображения на всех углах, которые вы хотите отобразить, а затем проблемно выберите правильное изображение для использования на основе вычисленный подшипник между двумя пунктами, которые вы используете. Однако это не будет изображение SVG, а изображение с обычным маркером.

Надеюсь, что это поможет в принятии некоторых решений относительно ваших маркеров карты.

Ответ 6

Как я могу повернуть изображение (изображение маркера) на карте Google V3?

У меня была та же проблема, и я решил ее с помощью следующего кода:

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

Я полагаю, что у вас есть переменная со значком, например:

var imagePath = 'img/customMarker.png';

Сначала нам нужно создать наши параметры маркера:

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

Создайте маркер:

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

И мы должны установить карту:

marker.setMap(map);

Теперь, если вы хотите повернуть изображение, вам нужно следующее:

  • Измените значение переменной imagePath на '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);

Что все.

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

Ответ 7

Мне удалось решить эту проблему довольно легко, но используя параметр marker.icon.rotation, указывающий на пользовательский символ, который использует синтаксис пути 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

}; 

При использовании angular -google-карт тривиально привязывать элемент управления ui для изменения треугольника. Оборот.

Как и с этим слайдером.

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

Но вы тоже можете использовать форум.

вот мой плукер http://plnkr.co/edit/x0egXI

Ответ 8

Вы можете вызывать yourmarker.setIcon(canvas.toDataUrlOrSomeThig) каждый раз при изменении изображения. Я не вижу ничего в ссылке api для непосредственного использования элемента canvas, кроме случаев, когда вы реализуете свой собственный google.maps.OverlayView.

Если вам нужна только анимация, вы можете использовать gif и добавить оптимизированную опцию маркера: false для нее.

Ответ 9

Самый простой способ - использовать свойство ротации для google.maps.Symbol. Просто установите его как свойство вашего значка при создании или обновлении маркера:

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

Plunker

Ответ 10

Вот как я применил мое изображение, повернутое, я считал маркер в виде наложения и что наложение - это позиция к позиции. Ниже будет добавлен код.

Без использования какой-либо дополнительной библиотеки она будет повернута. И вам нужно обходиться для добавления событий кликов и событий мыши для наложения, не похожих на события щелчка маркера.

С настройкой маркеров googleMap на карте будет добавлено использование памяти. Это также уменьшит потребление памяти пользовательских маркеров на вашей карте.

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

Ответ 11

Используя MarkerWithLabel Library, вы можете достичь этого следующим образом:

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

Ответ 12

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

Скажем, у вас есть скрытый холст:

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

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

Ответ 13

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