2016-04-24 6 views
-2

Я делаю приложение с API карт google, у которого есть JSON с координатами маркера. Затем я рисую полилинии между маркерами. Я также реализовал функцию с событием onclick, которое создает новый маркер внутри полилинии. Этот маркер должен отображать информацию о предыдущем маркере в полилинии (один из них был включен JSON, а не щелчок). Но я не знаю, как взять предыдущую вершину (маркер) выбранной полилинии.Карты Google: выберите предыдущий маркер на полилинии

enter image description here

Код:

(function() { 

window.onload = function() { 

var options = { 
zoom: 3, 
center: new google.maps.LatLng(37.09, -95.71), 
mapTypeId: google.maps.MapTypeId.HYBRID, 
noClear: true, 
panControl: true, 
scaleControl: false, 
streetViewControl:false, 
overviewMapControl:false, 
rotateControl:false, 
mapTypeControl: true, 
zoomControl: false, 
}; 
var map = new google.maps.Map(document.getElementById('map'), options); 

// JSON 
$.getJSON("loc.js", function(json) { 
    console.log(json); 
}); 

//Marker type 
var markers = []; 
var arr = []; 
var pinColor = "FE7569"; 
var pinImage = new google.maps.MarkerImage("http://labs.google.com/ridefinder/images/mm_20_red.png" + pinColor, 
    new google.maps.Size(21, 34), 
    new google.maps.Point(0,0), 
    new google.maps.Point(10, 34)); 

// JSON loop 
for (var i = 0, length = json.length; i < length; i++) { 
    var data = json[i], 
    latLng = new google.maps.LatLng(data.lat, data.lng); 
    arr.push(latLng); 

    // Create markers 
    var marker = new google.maps.Marker({ 
     position: latLng, 
     map: map, 
     icon: pinImage, 
    }); 
    infoBox(map, marker, data); 

    //Polylines 
    var flightPath = new google.maps.Polyline({ 
     path: json, 
     geodesic: true, 
     strokeColor: '#FF0000', 
     strokeOpacity: 1.0, 
     strokeWeight: 2, 
     map:map 
    }); 
     infoPoly(map, flightPath, data); 

    //Calculate polylines distance 
    google.maps.LatLng.prototype.kmTo = function(a){ 
     var e = Math, ra = e.PI/180; 
     var b = this.lat() * ra, c = a.lat() * ra, d = b - c; 
     var g = this.lng() * ra - a.lng() * ra; 
     var f = 2 * e.asin(e.sqrt(e.pow(e.sin(d/2), 2) + e.cos(b) * e.cos 
     (c) * e.pow(e.sin(g/2), 2))); 
     return f * 6378.137; 
    } 
    google.maps.Polyline.prototype.inKm = function(n){ 
     var a = this.getPath(n), len = a.getLength(), dist = 0; 
     for (var i=0; i < len-1; i++) { 
      dist += a.getAt(i).kmTo(a.getAt(i+1)); 
     } 
     return dist; 
    } 
} 

function infoBox(map, marker, data) { 
    var infoWindow = new google.maps.InfoWindow(); 
    google.maps.event.addListener(marker, "click", function(e) { 
     salta(data.tm); 
    }); 

    (function(marker, data) { 
     google.maps.event.addListener(marker, "click", function(e) { 
     salta(data.tm); 
     }); 
    })(marker, data); 
} 
//Create onclick marker on the polyline 
function infoPoly(map, flightPath, data){ 
google.maps.event.addListener(flightPath, 'click', function(event) { 
     mk = new google.maps.Marker({ 
     map: map, 
     position: event.latLng, 

     }); 
     markers.push(mk); 
     map.setZoom(17); 
     map.setCenter(mk.getPosition()); 
    }); 
    } 

    function drawPath() { 
     var coords = []; 
     for (var i = 0; i < markers.length; i++) { 
     coords.push(markers[i].getPosition()); 
     } 
     flightPath.setPath(coords); 
    } 

// Fit these bounds to the map 
var bounds = new google.maps.LatLngBounds(); 
for (var i = 0; i < arr.length; i++) { 
    bounds.extend(arr[i]); 
} 

map.fitBounds(bounds); 
//dist polylines 
distpoly = flightPath.inKm(); 
distpolyround = Math.round(distpoly); 
}; 
})(); 

Если я нажимаю на синюю стрелку, создать маркер на этой точке полилинии. Я, что маркер, принимает значения предыдущего.

+1

Это немного трудно понять концепцию. Не могли бы вы предоставить несколько скриншотов и, возможно, разместить больше своего кода ?! Вещи, которые я не получаю - вы создаете полилинию между двумя маркерами - одна находится в позиции щелчка. Где второй? А также - что это значит? - кто-то взял JSON_. Кроме того, вы должны просто создать глобальную переменную, которая будет отслеживать последнюю. Вы просто сохраните последнюю ссылку. –

+0

Если вы дали больше кода, я мог бы объяснить, как это сделать –

+0

Отредактировано: код сейчас, он завершен. Я пытаюсь лучше объяснить свою проблему. У меня есть JSON с latLng coodains. С этими координатами я создаю маркеры, а между ними - полилинии. Затем я создаю новый маркер (onclick) в некоторой точке внутри полилинии (между двумя маркерами, которые содержат координаты и другие данные). И проблема: мне нужен этот новый маркер (маркер onclick), берет содержащуюся информацию о предыдущем маркере. Это потому, что на карте не хватает путевых точек. – Andrew

ответ

0

Вы можете использовать метод geometry library .poly namespace isLocationOnEdge, чтобы определить, какой сегмент полилинии нажата точка (новый маркер).

//Create onclick marker on the polyline 
function infoPoly(map, flightPath, data) { 
    google.maps.event.addListener(flightPath, 'click', function(event) { 
    mk = new google.maps.Marker({ 
     map: map, 
     position: event.latLng, 

    }); 
    markers.push(mk); 
    map.setZoom(17); 
    map.setCenter(mk.getPosition()); 

    // find line segment. Iterate through the polyline checking each line segment. 
    // isLocationOnEdge takes a google.maps.Polyline as the second argument, so make one, 
    // then use it for the test. The default value of 10e-9 for the tolerance didn't work, 
    // a tolerance of 10e-6 seems to work. 
    var betweenStr = "result no found"; 
    var betweenStr = "result no found"; 
    for (var i=0; i<flightPath.getPath().getLength()-1; i++) { 
     var tempPoly = new google.maps.Polyline({ 
     path: [flightPath.getPath().getAt(i), flightPath.getPath().getAt(i+1)] 
     }) 
     if (google.maps.geometry.poly.isLocationOnEdge(mk.getPosition(), tempPoly, 10e-6)) { 
      betweenStr = "between "+i+ " and "+(i+1); 
     } 
    } 

    (function(mk, betweenStr) { 
     google.maps.event.addListener(mk, "click", function(e) { 
     infowindow.setContent(betweenStr+"<br>loc:" + this.getPosition().toUrlValue(6)); 
     infowindow.open(map, mk); 
     // salta(data.tm); 
     }); 
    })(mk, betweenStr); 

    google.maps.event.trigger(mk,'click'); 
    }); 

proof of concept fiddle

фрагмент кода:

var infowindow = new google.maps.InfoWindow(); 
 
(function() { 
 

 
    window.onload = function() { 
 

 
    var options = { 
 
     zoom: 3, 
 
     center: new google.maps.LatLng(37.09, -95.71), 
 
     mapTypeId: google.maps.MapTypeId.HYBRID, 
 
    }; 
 
    var map = new google.maps.Map(document.getElementById('map'), options); 
 

 
    //Marker type 
 
    var markers = []; 
 
    var arr = []; 
 
    var pinColor = "FE7569"; 
 
    var pinImage = "http://labs.google.com/ridefinder/images/mm_20_red.png"; 
 

 
    // JSON loop 
 
    for (var i = 0, length = json.length; i < length; i++) { 
 
     var data = json[i], 
 
     latLng = new google.maps.LatLng(data.lat, data.lng); 
 
     arr.push(latLng); 
 

 
     // Create markers 
 
     var marker = new google.maps.Marker({ 
 
     position: latLng, 
 
     map: map, 
 
     icon: pinImage, 
 
     }); 
 
     infoBox(map, marker, data); 
 

 
     //Polylines 
 
     var flightPath = new google.maps.Polyline({ 
 
     path: json, 
 
     geodesic: true, 
 
     strokeColor: '#FF0000', 
 
     strokeOpacity: 1.0, 
 
     strokeWeight: 2, 
 
     map: map 
 
     }); 
 
     infoPoly(map, flightPath, data); 
 
    } 
 

 
    function infoBox(map, marker, data) { 
 
     var infoWindow = new google.maps.InfoWindow(); 
 
     google.maps.event.addListener(marker, "click", function(e) { 
 
      infowindow.setContent("tm:" + data.tm + "<br>loc:" + this.getPosition().toUrlValue(6)); 
 
      infowindow.open(map, marker); 
 
      // salta(data.tm); 
 
     }); 
 

 
     (function(marker, data) { 
 
      google.maps.event.addListener(marker, "click", function(e) { 
 
      infowindow.setContent("tm:" + data.tm + "<br>loc:" + this.getPosition().toUrlValue(6)); 
 
      infowindow.open(map, marker); 
 
      // salta(data.tm); 
 
      }); 
 
     })(marker, data); 
 
     } 
 
     //Create onclick marker on the polyline 
 

 
    function infoPoly(map, flightPath, data) { 
 
     google.maps.event.addListener(flightPath, 'click', function(event) { 
 
     mk = new google.maps.Marker({ 
 
      map: map, 
 
      position: event.latLng, 
 

 
     }); 
 
     markers.push(mk); 
 
     map.setZoom(17); 
 
     map.setCenter(mk.getPosition()); 
 

 
     // find line segment. Iterate through the polyline checking each line segment. 
 
     // isLocationOnEdge takes a google.maps.Polyline as the second argument, so make one, 
 
     // then use it for the test. The default value of 10e-9 for the tolerance didn't work, 
 
     // a tolerance of 10e-6 seems to work. 
 
     var betweenStr = "result no found"; 
 
     for (var i = 0; i < flightPath.getPath().getLength() - 1; i++) { 
 
      var tempPoly = new google.maps.Polyline({ 
 
      path: [flightPath.getPath().getAt(i), flightPath.getPath().getAt(i + 1)] 
 
      }) 
 
      if (google.maps.geometry.poly.isLocationOnEdge(mk.getPosition(), tempPoly, 10e-6)) { 
 
      betweenStr = "between " + i + " and " + (i + 1); 
 
      } 
 
     } 
 

 
     (function(mk, betweenStr) { 
 
      google.maps.event.addListener(mk, "click", function(e) { 
 
      infowindow.setContent(betweenStr + "<br>loc:" + this.getPosition().toUrlValue(6)); 
 
      infowindow.open(map, mk); 
 
      // salta(data.tm); 
 
      }); 
 
     })(mk, betweenStr); 
 

 
     google.maps.event.trigger(mk, 'click'); 
 
     }); 
 
    } 
 

 
    function drawPath() { 
 
     var coords = []; 
 
     for (var i = 0; i < markers.length; i++) { 
 
     coords.push(markers[i].getPosition()); 
 
     } 
 
     flightPath.setPath(coords); 
 
    } 
 

 
    // Fit these bounds to the map 
 
    var bounds = new google.maps.LatLngBounds(); 
 
    for (var i = 0; i < arr.length; i++) { 
 
     bounds.extend(arr[i]); 
 
    } 
 

 
    map.fitBounds(bounds); 
 
    //dist polylines 
 
    distpoly = flightPath.inKm(); 
 
    distpolyround = Math.round(distpoly); 
 
    }; 
 
})(); 
 

 
var json = [{ 
 
    lat: 38.931808, 
 
    lng: -74.906606, 
 
    tm: 0 
 
}, { 
 
    lat: 38.932442, 
 
    lng: -74.905147, 
 
    tm: 1 
 
}, { 
 
    lat: 38.93311, 
 
    lng: -74.903473, 
 
    tm: 2 
 
}, { 
 
    lat: 38.933777, 
 
    lng: -74.901671, 
 
    tm: 3 
 
}, { 
 
    lat: 38.930739, 
 
    lng: -74.912528, 
 
    tm: 1000 
 
}];
html, 
 
body, 
 
#map { 
 
    height: 100%; 
 
    width: 100%; 
 
    margin: 0px; 
 
    padding: 0px 
 
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script> 
 
<div id="map"></div>

+0

Ничего себе. Невероятная работа! Он работает лучше, чем я ожидал! – Andrew

+0

Теперь я вижу, что есть проблема со временем. По какой-то причине максимальное значение времени, которое ему требуется, составляет 450. С этого момента всегда берется 350 и всегда прыгает к тому времени. Координаты выполняются правильно. Вы знаете, как это решить? Благодарю. – Andrew

+0

Также я вижу в маркере со временем 1056, он принимает правильное время до конечной точки (1356). Таким образом, диапазон невыбранной точки равен (350, 1056) aprox. – Andrew

0

INITIALIZING
При создании этих маркеров в цикле for, добавьте их в [структуры данных] в map, что вы определяете (пустой) перед циклом. На маркерах карты будут сохранены. Их ключи - конкатенированные лат/lng.

  • var initial_markers = {}; //before for loop
  • initial_markers[data.lat+"-"+data.lng] = marker; //after each marker initialization
  • сосчитать их, так что вы знаете, сколько есть initial_marker_count, потому что вы не можете получить длину размера [структуры данных] map

ОБНАРУЖЕНИЕ
Когда вы нажмете на полилинию, я не думаю, что вы можете получить именно ту часть полилинии, на которую щелкнули, поэтому вам нужно получить его самостоятельно. Шаги:

  • Получить координаты события мыши
  • Loop через маркеры
  • Возьмите их координаты
  • Проверьте, если выбранная точка на карте находится на линии между этими двумя точками
  • Если есть, взять первый из этих двух точек

ОБНАРУЖЕНИЯ псевдокода

var prev_marker; 
for (var i=initial_markers; i<initial_marker_count-2; i++) { 
    if(isPointOnLine(initial_markers[i], initial_markers[i+1], clicked_point) { 
     prev_marker = initial_markers[i]; 
     break; 
    } 
} 

Единственная причина, я говорю, что это псевдокод, потому что я не знаю, Hor найти, если точка находится на линии между двумя точками в Google картах. И вы должны написать, что isPointOnLine() функции. Кроме того - идея дается. Надеюсь, вы это оцените.

 Смежные вопросы

  • Нет связанных вопросов^_^