Контекстное меню Google Map V3 - PullRequest
13 голосов
/ 24 августа 2011

Я ищу библиотеку контекстного меню Google Map V3.Я нашел несколько примеров кода здесь

  1. Блог Gizzmo
  2. Советы по API Google
  3. GMap3
  4. Как я получил ..

Вопрос переполнения стека Google maps v3 - Доступно контекстное меню? апреля тоже только что пришлос приведенными выше примерами.Так же Gmap3 добавил простое контекстное меню .

Но, возможно, кто-то инкапсулировал примеры в многократно используемую библиотеку или тем временем нашел что-то.Очевидно, было что-то для V2.

- Обновлено 2012-05-31 -

Я нашел еще один http://googlemapsmania.blogspot.de/2012/04/create-google-maps-context-menu.html, но не нашелесть время, чтобы проверить это.

Ответы [ 3 ]

9 голосов
/ 09 июня 2012

Я не думаю, что вам нужна библиотека для этого.Я бы начал с попытки:

var contextMenu = google.maps.event.addListener(
        map,
        "rightclick",
        function( event ) {
            // use JS Dom methods to create the menu
            // use event.pixel.x and event.pixel.y 
            // to position menu at mouse position
            console.log( event );
        }
    );

Предполагается, что ваша карта была создана с помощью:

var map = new google.maps.map( { [map options] } );

Объект event внутри обратного вызова имеет 4 свойства

  1. latLng
  2. ma
  3. pixel

, где pixel.x и pixel.y - это смещение, при котором произошло событие щелчка -отсчитывается от верхнего левого угла холста, содержащего объект карты.

3 голосов
/ 29 сентября 2014

Я создал работающую JS Fiddle для отображения контекстного меню, а также возможность иметь интерактивные элементы в этом контекстном меню.

Показывает интерактивное контекстное меню, если щелкнуть правой кнопкой мыши маркер на карте Google. В основном это использует OverlayView на карте. Кстати, это просто демо.

var loc, map, marker, contextMenu;

ContextMenu.prototype = new google.maps.OverlayView();

/**
  * onAdd is called when the map's panes are ready and the overlay has been
  * added to the map.
  */
ContextMenu.prototype.onAdd = function() {

    $("<div id='cMenu' class='context-menu-marker'></div>").appendTo(document.body);
    var divOuter = $("#cMenu").get(0);

    for(var i=0;i < this.menuItems.length;i++) {
        var mItem = this.menuItems[i];
        $('<div id="' + mItem.id + '" class="options-marker">' +
          mItem.label + '</div>').appendTo(divOuter);
    }

    this.div_ = divOuter;

    // Add the element to the "overlayLayer" pane.
    var panes = this.getPanes();
    //panes.overlayLayer.appendChild();
    panes.overlayMouseTarget.appendChild(this.div_);

    var me = this;

    for(var i=0;i < this.menuItems.length;i++) {
        var mItem = this.menuItems[i];

        var func = function() {
           me.clickedItem = this.id;
           google.maps.event.trigger(me, 'click');
        };

        google.maps.event.addDomListener($("#" + mItem.id).get(0), 'click', $.proxy(func, mItem));
    }


    google.maps.event.addListener(me, 'click', function() {
       alert(me.clickedItem); 
    });

};

ContextMenu.prototype.draw = function() {
    var div = this.div_;
    div.style.left = '0px';
    div.style.top = '0px';
    div.style.width = '100px';
    div.style.height = '50px';
};

// The onRemove() method will be called automatically from the API if
// we ever set the overlay's map property to 'null'.
ContextMenu.prototype.onRemove = function() {
    this.div_.parentNode.removeChild(this.div_);
    this.div_ = null;
};

// Set the visibility to 'hidden' or 'visible'.
ContextMenu.prototype.hide = function() {
  if (this.div_) {
    // The visibility property must be a string enclosed in quotes.
    this.div_.style.visibility = 'hidden';
  }
};

ContextMenu.prototype.show = function(cpx) {
  if (this.div_) {
    var div = this.div_;
    div.style.left = cpx.x + 'px';
    div.style.top = cpx.y + 'px';

    this.div_.style.visibility = 'visible';
  }
};

function ContextMenu(map,options) {
    options = options || {}; //in case no options are passed to the constructor
    this.setMap(map); //tells the overlay which map it needs to draw on
    this.mapDiv = map.getDiv(); //Div container that the map exists in
    this.menuItems = options.menuItems || {}; //specific to context menus
    this.isVisible = false; //used to hide or show the context menu
}

function initialize() {

    loc = new google.maps.LatLng(62.323907, -150.109291);

    var options = {};
    var menuItems=[];

    menuItems.push({id:"zoomIn", className:'context_menu_item', eventName:'zoom_in_click', label:'Zoom in'});
    menuItems.push({id:"zoomOut", className:'context_menu_item', eventName:'zoom_out_click', label:'Zoom out'});


    options.menuItems = menuItems;
    //=========================================

    map = new google.maps.Map(document.getElementById("map"), {
        zoom: 12,
        center: loc,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    marker = new google.maps.Marker({
        map: map,
        position: loc,
        visible: true
    });

    contextMenu = new ContextMenu(map, options);

    google.maps.event.addListener(marker, 'rightclick', function(mouseEvent){
        contextMenu.hide();
        this.clickedMarker_ = this;
        var overlayProjection = contextMenu.getProjection();
        var cpx = overlayProjection.fromLatLngToContainerPixel(mouseEvent.latLng);
        contextMenu.show(cpx);

        map.setOptions({ draggableCursor: 'pointer' });
    });

    // Hide context menu on several events
    google.maps.event.addListener(map,'click', function(){
        map.setOptions({ draggableCursor: 'grab' });
        contextMenu.hide();
    });

}

google.maps.event.addDomListener(window, 'load', initialize);

Скриптовая ссылка:

http://jsfiddle.net/jEhJ3/3409/

1 голос
/ 21 июля 2015

Перейти на этот демонстрационный веб-сайт: http://easysublease.org/mapcoverjs/

Для контекстного меню я не предлагаю реализовывать один подкласс класса overlayView, предоставляемый API Карт Google. Во-первых, один экземпляр подкласса overlayView должен быть добавлен к пяти панелям, предоставленным Google. Скорее всего, нужно добавить этот экземпляр на панель overlayMouseTarget. Но , этот экземпляр "затенен" другими домами над ним. Поэтому обычное исходное событие браузера, такое как mouseover, mouseout, не может достичь этого экземпляра.

Нужно использовать метод Google Maps API: addDomListener, чтобы справиться с этим ( почему? ). Требуется много кода JavaScript для реализации различных обработчиков событий, много добавлений и удалений классов CSS, чтобы реализовать некоторые визуальные эффекты, что можно сделать, используя несколько строк кода CSS , если этот экземпляр находится за пределами карты. контейнер.

Таким образом, на самом деле преобразование одного внешнего dom вне контейнера карты Google в одно контекстное меню имеет то преимущество, что он может получать оригинальные события DOM из браузера. Также использование некоторой внешней библиотеки может заставить цель вести себя лучше. Как контекстное меню, оно должно быть способным обрабатывать не только исходные события, но и события из Map.

----------- см. Варианты реализации ниже ------------------------

В части HTML карты это код:

<div id="mapcover">
  <div id="mapcover-map"></div> <!-- this is map container-->
  <div id="demoControlPanel" class="mc-static2mapcontainer panel">I am map UI control button's container, I think one can use jQuery UI to make me look better<br><br>
    <div id="zoom-in-control" class="text-center">zoomIn</div>
    <div id="zoom-out-control" class="text-center">zoomOut</div>
  </div>
  <div id="demoContextPanel" class="mc-ascontextmenu panel">

    I am map context menu container, you can sytle me and add logic to me, just as normal DOM nodes.
    since I am not in Map Container at all! 
    <div class="text-center">
      <div role="group" aria-label="..." class="btn-group">
        <button id="place-marker1" type="button" class="btn btn-default">Marker1</button>
        <button id="place-marker2" type="button" class="btn btn-default">Marker2</button>
      </div>
    </div>
    <div class="form-group">
      <label for="content-marker1">Content of next Marker1</label>
      <input id="content-marker1" type="text" placeholder="New of Marker1!" class="form-control">
    </div>
  </div>
</div>

Он показывает, как один разработчик может преобразовать один внешний DOM (id = demoContextPanel) в одно контекстное меню карты, просто добавив один класс CSS ".mc-ascontextmenu"! На этих страницах используется mapcover.js, который помогает разработчику управлять некоторыми ключевыми компонентами Map, такими как пользовательские интерфейсы управления картой, контекстное меню и настраиваемые маркеры. Тогда разработчики имеют полную свободу в оформлении интерфейсов своих карт.

Если вам нужно больше, вы можете перейти на его Github, см. Readme.md: https://github.com/bovetliu/mapcover

...