How can I drag an icon inside google maps?

后端 未结 2 1247
醉梦人生
醉梦人生 2020-12-11 23:07

I would like to be able to have an icon, placed outside of a google map. Then i would like to have this icon dragged and dropped INTO google maps and use it as a google maps

相关标签:
2条回答
  • 2020-12-11 23:36

    See this post in the Google Maps Javascript API v3 group

    Points to this example: http://www.wolfpil.de/v3/drag-from-outside.html

    code snippet (unobfuscated)

    var map, iw, drag_area, actual, mark;
    var overview, zIndex = 0;
    
    function helper() {
      this.setMap(map);
      this.draw = function() {};
    }
    helper.prototype = new google.maps.OverlayView();
    
    function fillMarker(icon) {
      var div = document.createElement("div");
      div.style.backgroundImage = "url(" + icon + ")";
      var left;
      if (mark.id == "m1") {
        left = "0px";
      } else if (mark.id == "m2") {
        left = "50px";
      } else if (mark.id == "m3") {
        left = "100px";
      }
      div.style.left = left;
      div.id = mark.id;
      div.className = "drag";
      div.onmousedown = div.ontouchstart = initDrag;
      drag_area.replaceChild(div, mark);
      mark = null;
    }
    
    function createDraggedMarker(latlng, icon) {
      var icon = {
        url: icon,
        size: new google.maps.Size(32, 32),
        anchor: new google.maps.Point(15, 32)
      };
      var marker = new google.maps.Marker({
        position: latlng,
        map: map,
        clickable: true,
        draggable: true,
        crossOnDrag: false,
        optimized: false,
        icon: icon,
        zIndex: zIndex
      });
      google.maps.event.addListener(marker, "click", function() {
        actual = marker;
        var lat = actual.getPosition().lat();
        var lng = actual.getPosition().lng();
        var contentStr = "<div class='infowindow'>" + lat.toFixed(6) + ", " + lng.toFixed(6) + "<\/div>";
        iw.setContent(contentStr);
        iw.open(map, this);
      });
      google.maps.event.addListener(marker, "dragstart", function() {
        if (actual == marker) iw.close();
        zIndex += 1;
        marker.setZIndex(zIndex);
      });
    }
    
    function initDrag(evt) {
      function getPt(evt) {
        var pt = {};
        if (evt && evt.touches && evt.touches.length) {
          pt.x = evt.touches[0].clientX;
          pt.y = evt.touches[0].clientY;
        } else {
          if (!evt) var evt = window.event;
          pt.x = evt.clientX;
          pt.y = evt.clientY;
        }
        return pt;
      };
      var drag = function(mEvt) {
        if (mark && mark.className == "drag") {
          var pt = getPt(mEvt),
            x = pt.x - o.x,
            y = pt.y - o.y;
          mark.style.left = (mark.x + x) + "px";
          mark.style.top = (mark.y + y) + "px";
          mark.onmouseup = mark.ontouchend = function() {
            var mapDiv = map.getDiv(),
              mapLeft = mapDiv.offsetLeft,
              mapTop = mapDiv.offsetTop,
              mapWidth = mapDiv.offsetWidth,
              mapHeight = mapDiv.offsetHeight;
            var dragLeft = drag_area.offsetLeft,
              dragTop = drag_area.offsetTop,
              iconWidth = mark.offsetWidth,
              iconHeight = mark.offsetHeight;
            var newLeft = mark.offsetLeft + dragLeft + iconWidth / 2;
            var newTop = mark.offsetTop + dragTop + iconHeight / 2;
            if (dragLeft > mapLeft && newLeft < (mapLeft + mapWidth) && newTop > mapTop && newTop < (mapTop + mapHeight)) {
              var offset = 1;
              var divPt = new google.maps.Point(newLeft - mapLeft - offset, newTop - mapTop + (iconHeight / 2));
              var proj = overview.getProjection();
              var latlng = proj.fromContainerPixelToLatLng(divPt);
              var icon = mark.style.backgroundImage.slice(4, -1).replace(/"/g, "");
              createDraggedMarker(latlng, icon);
              fillMarker(icon);
            }
          };
        }
        return false;
      };
      if (!evt) var evt = window.event;
      mark = evt.target ? evt.target : evt.srcElement ? evt.srcElement : evt.touches ? evt.touches[0].target : null;
      if (mark.className != "drag") {
        if (d.cancelable) d.preventDefault();
        mark = null;
        return;
      } else {
        zIndex++;
        mark.style.zIndex = zIndex.toString();
        mark.x = mark.offsetLeft;
        mark.y = mark.offsetTop;
        var o = getPt(evt);
        if (evt.type === "touchstart") {
          mark.onmousedown = null;
          mark.ontouchmove = drag;
          mark.ontouchend = function() {
            mark.ontouchmove = null;
            mark.ontouchend = null;
            mark.ontouchstart = initDrag;
          };
        } else {
          document.onmousemove = drag;
          document.onmouseup = function() {
            document.onmousemove = null;
            document.onmouseup = null;
            if (mark) mark = null;
          };
        }
      }
      return false;
    }
    
    function initialize() {
      var mapOptions = {
        center: new google.maps.LatLng(52.052491, 9.84375),
        zoom: 4,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        streetViewControl: false,
        mapTypeControlOptions: {
          mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.TERRAIN]
        },
        panControl: false,
        zoomControlOptions: {
          style: google.maps.ZoomControlStyle.SMALL
        }
      };
      map = new google.maps.Map(document.getElementById("map"), mapOptions);
      iw = new google.maps.InfoWindow();
      google.maps.event.addListener(map, "click", function() {
        if (iw) iw.close();
      });
      drag_area = document.getElementById("markers");
      var divArray = drag_area.getElementsByTagName("div");
      for (var i = 0; i < divArray.length; i++) {
        var div = divArray[i];
        div.onmousedown = div.ontouchstart = initDrag;
      }
      overview = new helper();
    }
    google.maps.event.addDomListener(window, 'load', initialize);
    body,
    html {
      height: 100%;
      width: 100%;
    }
    #map {
      float: left;
      margin: 0 25px 10px 14px;
      width: 64%;
      height: 70%;
    }
    #desc {
      float: left;
      margin: 0 25px 10px 20px;
      width: 10em;
    }
    #markers {
      position: absolute;
      top: 140px;
      left: 70%;
      width: 200px;
      height: 110px;
    }
    .drag {
      position: absolute;
      width: 32px;
      height: 32px;
    }
    .infowindow {
      margin-top: 20px;
      width: 180px;
      height: 60px;
    }
    @media screen and (max-width: 890px) {
      body,
      html,
      #map {
        margin: 0;
      }
      #map {
        width: 100%;
        height: 50%;
      }
      #desc {
        margin: 100px 14px 0;
        width: 93%;
      }
      .include >b {
        float: right;
        margin-top: 17px;
      }
      #markers {
        /* center horizontal and do not overlap the map */
        position: absolute;
        top: 50%;
        left: 50%;
        width: 10em;
        height: 6em;
        margin-top: 5em;
        margin-left: -5em;
      }
      #markers > p {
        margin-top: 0;
        font-size: 80%;
      }
      .infowindow {
        margin-top: 10px;
        width: 150px;
        height: 25px;
      }
    }
    <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry,places&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
    <h3>Drag Markers to the Map</h3>
    
    <div id="map"></div>
    <div id="desc"></div>
    <div id="markers">
      <p>Drag the markers to a location on the map</p>
      <div id="m1" class="drag" style="left:0; background-image: url('http://maps.google.com/mapfiles/ms/micons/blue.png')"></div>
      <div id="m2" class="drag" style="left:50px; background-image: url('http://maps.google.com/mapfiles/ms/micons/green.png')"></div>
      <div id="m3" class="drag" style="left:100px; background-image: url('http://maps.google.com/mapfiles/ms/micons/yellow.png')"></div>
    </div>

    0 讨论(0)
  • 2020-12-11 23:50

    The accepted answer contains some obfuscated code. It took me quite a lot of time to find something a bit more tangible so since this answer comes up first in google search I thought will share something for a good start.

    Note: window.map is where I store reference to my map. Also for cross-browser compatibility I am using jquery-ui draggable (was already included in my project so why not reusing it).

        var pixelToLatlng = function(xcoor, ycoor)
        {
            var ne = window.map.getBounds().getNorthEast();
            var sw = window.map.getBounds().getSouthWest();
            var projection = window.map.getProjection();
            var topRight = projection.fromLatLngToPoint(ne);
            var bottomLeft = projection.fromLatLngToPoint(sw);
            var scale = 1 << window.map.getZoom();
    
            var newLatlng = projection.fromPointToLatLng(new google.maps.Point(xcoor / scale + bottomLeft.x, ycoor / scale + topRight.y));
            return newLatlng;
        };
    
        $(".draggable").draggable(
        {
            helper: "clone",
            appendTo: window.map.getDiv(),
            cursorAt: { left: 5, top: 5 },
            stop: function(event, ui)
            {
                var wrapper = $(window.map.getDiv());
                var map_div_pos = wrapper.offset();
                var map_div_border_left = parseInt(wrapper.css("border-left-width"),10);
                var map_div_border_top = parseInt(wrapper.css("border-top-width"),10);
    
                var mouse_pos = ui.helper.offset();
                lat_lng = pixelToLatlng(mouse_pos.left - map_div_border_left - map_div_pos.left, mouse_pos.top - map_div_border_top - map_div_pos.top);
    
                window.add_group_marker = new google.maps.Marker(
                {
                    position: lat_lng,
                    map: window.map,
                    zIndex: Math.round(lat_lng.lat()*-100000)<<5
                });
            }
        });
    

    Credits:

    • pixelToLatlng was found here: http://www.magicalrosebud.com/how-to-use-googlemaps-api-frompointtolatlng/

    • Hints on calculating x/y when using jquery-ui draggable: How do I get position x and y from jQuery ui draggable?

    0 讨论(0)
提交回复
热议问题