I finally succeed to have polygons drag&drop behavior in google maps.
The way I did :
-1- the map MUST be draggable in its initial options (even if it is the polygon I will drag)
-2- polygon callback must then prevent the map from panning (saving the center at mousedown and re-affecting this center at every mousemove)
-3- register mousemove and mouseup on both map and polygon(s), you never know where the pointer will be due to the lag
-4- re-compute every point of the polygon at every mouvemove by offsetting them
(js code follows)
However I'm not very happy with performances. It may be due to item #4 but has impact on item #3. Also when you drag the polygon outside the map and then re-entering the map, there is a strange shaking of the map. At last when I zoom-unzoom with the mouse wheel in the middle of a drag, there is a little
re-offseting at the first move after the zoom (since saved map center do not correspond well to the new zoomed map).
My question : does someone better resolved the dragging polygon problem ?
My wish list for googlers
-1- event triggered on polygon even if the map is not draggable
-2- a mechanism to have the polygon receiving all the events when it is dragged
-3- a way to offset all the polygon points at the same time (and then a way to link a polygon with something else in the MVCObject archi. model)
-4- a way to have color gradients inside polygons (well it's not santa's wish list maybe.... ;-)
// GLOBAL VARS
var grabPoly;
var grabPolyLoc;
var grabMapLoc;
// SOMEWHERE IN MY CODE
var polyOptions = {
strokeColor: '#0000FF',
strokeOpacity: 0.6,
strokeWeight: 1,
clickable: true
}
var poly0 = new google.maps.Polygon(polyOptions);
path0 = new google.maps.MVCArray();
path0.push(new google.maps.LatLng(48.24370129200754,1.3039131164550781));
path0.push(new google.maps.LatLng(47.50681416405265,3.720905303955078));
path0.push(new google.maps.LatLng(46.96975999867877,1.8532295227050781));
poly0.setPath(path0);
poly0.setMap(map);
google.maps.event.addListener(poly0,'mousedown',function(evt){
grabPoly = this;
grabPolyLoc = evt.latLng;
grabMapLoc = map.getCenter();
});
google.maps.event.addListener(poly0,'mouseup',function(evt){
if (grabPoly!=null) {
grabPoly = null;
}
});
google.maps.event.addListener(poly0,'mousemove',function(evt){
if (grabPoly != null){
map.setCenter(grabMapLoc);
var path1 = new google.maps.MVCArray();
for (var j=0; j<grabPoly.getPath().getLength(); j++) {
var pt = grabPoly.getPath().getAt(j);
var newlon = pt.lng()+evt.latLng.lng()-grabPolyLoc.lng();
var newlat = pt.lat()+evt.latLng.lat()-grabPolyLoc.lat();
path1.push(new google.maps.LatLng(newlat, newlon));
grabPoly.getPath().setAt(j, new google.maps.LatLng(newlat, newlon));
}
grabPoly.setPath(path1);
grabPolyLoc = evt.latLng;
}
});
google.maps.event.addListener(map,'mousemove',function(evt){
if (grabPoly != null){
map.setCenter(grabMapLoc);
var path1 = new google.maps.MVCArray();
for (var j=0; j<grabPoly.getPath().getLength(); j++) {
var pt = grabPoly.getPath().getAt(j);
var newlon = pt.lng()+evt.latLng.lng()-grabPolyLoc.lng();
var newlat = pt.lat()+evt.latLng.lat()-grabPolyLoc.lat();
path1.push(new google.maps.LatLng(newlat, newlon));
grabPoly.getPath().setAt(j, new google.maps.LatLng(newlat, newlon));
}
grabPoly.setPath(path1);
grabPolyLoc = evt.latLng;
}
});
google.maps.event.addListener(map, 'mouseup', function(){
if (grabPoly != null)
grabPoly = null;
});