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