2012-05-22 98 views
12

我創建了一個Google地圖並在其上繪製了折線。然後,我在polyine的開頭添加了一個標記(與多段線的起始座標相同的座標)。將Google地圖V3標記拖動到折線

我想要做的就是抓住並拖動標記,但讓它「粘」到折線上,這樣只能沿着折線拖動它,而不會離開或到它的側面。

是否可以將可拖動標記限制在GM V3中的路徑中?如果沒有,任何人都可以考慮如何做到這一點?當用戶放棄標記時,可能會將標記貼到路徑上的最近點,但我更願意沿着「拖動路徑」效果更平滑。

很高興收到ArcGis的建議。沒有提供代碼,因爲這是理論上更多的問題。

讓我知道是否需要進一步解釋。

在此先感謝

回答

13

好吧,所以我設法解決這個問題。它不完美,我相信它可以改進,但這是我想出的一般概念:

我從一個GPX文件創建一個latlng點的數組,但他們只記錄點每20秒或者。這不是每對由GPX記錄點之間足夠的粒度爲我的目的所以我所做的是我填充點的陣列約10點(在直線):

$.each(array_of_points_to_pad, function(key, pt) { 
    var current_point = pt;//The current point 
    var next_point = array_of_points_to_pad[key + 1];//The point immediately after the current point 

    //Check that we're not on the last point 
    if (typeof next_point !== 'undefined') { 
     //Get a 10th of the difference in latitude between current and next points 
     var lat_incr = (next_point.lat() - current_point.lat())/10; 

     //Get a 10th of the difference in longitude between current and next points 
     var lng_incr = (next_point.lng() - current_point.lng())/10; 

     //Add the current point to a new padded_points array 
     padded_points.push(current_point); 

     //Now add 10 additional points at lat_incr & lng_incr intervals between current and next points (in the new padded_points array) 
     for (var i = 1; i <= 10; i++) { 
      var new_pt = new google.maps.LatLng(current_point.lat() + (i * lat_incr), current_point.lng() + (i * lng_incr)); 
      padded_points.push(new_pt); 
     } 
    } 
}); 

現在,我有一個更精細的點陣,我用它來繪製折線。填充折線與沒有填充的繪製折線看起來沒有區別,因爲所有附加點位於現有點之間的線性「現成烏鴉」線上。

var line = new google.maps.Polyline({ 
    path: polyline_path_points_padded, 
    strokeColor: '#ff0000', 
    strokeOpacity: 1.0, 
    strokeWeight: 2 
}); 
line.setMap(map); 

現在我在該行的開頭添加一個拖動的標記:

var latLng = new google.maps.LatLng(startlat,startlng); 
var marker = new google.maps.Marker({ 
    position: latLng, 
    map: map, 
    draggable:true 
}); 

所有剩下要做的就是控制這個標誌的阻力和dragend事件:

google.maps.event.addDomListener(marker,'dragend',function(e){ 
    marker.setPosition(find_closest_point_on_path(e.latLng,padded_points)); 
}); 

google.maps.event.addDomListener(marker,'drag',function(e){ 
    marker.setPosition(find_closest_point_on_path(e.latLng,padded_points)); 
}); 

在這裏,我們只需將標記的latLng發送到函數find_closest_point_on_path(),同時拖動標記並放棄標記。我們發送填充的點陣列作爲搜索路徑。

功能如下:

function find_closest_point_on_path(marker_pt,path_pts){ 
    distances = new Array(); 
    distance_keys = new Array(); 
    $.each(path_pts,function(key, path_pt){ 
     var R = 6371; // km 
     var dLat = (path_pt.lat()-marker_pt.lat()).toRad(); 
     var dLon = (path_pt.lng()-marker_pt.lng()).toRad(); 
     var lat1 = marker_pt.lat().toRad(); 
     var lat2 = path_pt.lat().toRad(); 

     var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
       Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
     var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
     var d = R * c; 
     //Store the key of the point on the path that matches this distance 
     distance_keys[d] = key; 

    }); 
      //Return the latLng pt on the path for the second closest point 
    return path_pts[distance_keys[_.min(distances)]+1]; 
} 

這個函數(有學位的幫助弧度功能)這是什麼發現線路上的標記位置和所有點之間的距離。然後它找到最接近標記的點並返回該標記之後的下一個最近點的座標。這樣,當您拖放標記時,它會「捕捉」到下一個點(而不是卡在一個點上)。

工作JS小提琴下面:

http://jsfiddle.net/Z5GwW/4/

有沒有跨瀏覽器測試。使用Chrome最新版本。

+1

試圖在解決這個問題我自己一個移動平臺,所有這些trig函數對於運行o的表達式都有點嚇人在每一個拖拽tic中,我是否可以建議計算一個簡單的[曼哈頓距離](http://en.wikipedia.org/wiki/Taxicab_geometry),它應該足夠準確,並且只使用基本算術運算 – jmaculate

0

謝謝你的解決方案。

爲了得到它,而不依賴的工作,我不得不修改幾行:)

首先,檢查toRad(函數存在:

if (typeof(Number.prototype.toRad) === "undefined") { 
 
\t Number.prototype.toRad = function() { 
 
\t  return this * Math.PI/180; 
 
\t } 
 
\t }

而且還, 去掉 _。通過更換返回代碼依賴:

return path_pts[distance_keys[ Math.min(...distances) ]+1];

最後,包括距離[]之前distancekeys []

distances[key] = d; 
 
distance_keys[d] = key;

相關問題