2016-04-24 13 views
-2

Ich mache eine Anwendung mit Google Maps API, die ein JSON mit den Koordinaten des Markers haben. Dann zeichne ich Polylinien zwischen den Markern. Ich habe auch eine Funktion mit einem onclick -Ereignis implementiert, die einen neuen Marker innerhalb der Polylinie erzeugt. Dieser Marker muss Informationen des vorherigen Markers in der Polylinie anzeigen (der von JSON genommene, nicht angeklickte). Aber ich weiß nicht, wie ich den vorherigen Eckpunkt (Marker) einer ausgewählten Polylinie nehmen soll.Google Maps: Vorherigen Marker auf Polylinie auswählen

enter image description here

Code:

(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); 
}; 
})(); 

Wenn ich in dem blauen Pfeil klicken, erstelle ich eine Markierung auf dem Punkt der Polylinie. I dieser Marker nimmt die Werte des vorherigen.

+1

Es ist ein bisschen schwer, das Konzept zu verstehen. Könntest du ein paar Screenshots bereitstellen und vielleicht mehr von deinem Code posten ?! Dinge, die ich nicht verstehe, sind - Sie erstellen Polylinie zwischen 2 Markern - einer ist an der Stelle des Klicks. Wo ist der Zweite? Und auch - was das bedeutet? - _derjenige, der von JSON_ genommen wurde. Abgesehen davon - Sie sollten nur eine globale Variable erstellen, die den letzten Überblick behält. Sie speichern nur die Referenz des letzten. –

+0

Wenn Sie mehr Code gaben, könnte ich erklären, wie es geht –

+0

Bearbeitet: Der Code jetzt, es ist abgeschlossen. Ich versuche mein Problem besser zu erklären. Ich habe ein JSON mit den LatLng Coodinaten. Mit diesen Koordinaten erstelle ich Marker und dazwischen Polylinien. Dann erstelle ich einen neuen Marker (onclick) an einem Punkt innerhalb der Polylinie (zwischen den 2 Markern, die die Koordinaten und andere Daten enthalten). Und das Problem: Ich brauche diesen neuen Marker (onclick marker), nehme die enthaltenen Informationen des vorherigen Markers. Dies liegt daran, dass ich nicht genügend Wegpunkte in der Karte habe. – Andrew

Antwort

0

Mit der Methode geometry library .poly namespace isLocationOnEdge können Sie bestimmen, auf welchem ​​Segment der Polylinie der angeklickte Punkt (neue Markierung) aktiviert ist.

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

Code-Schnipsel:

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

Wow. Unglaubliche Arbeit !! Es funktioniert besser als ich erwartet habe !! – Andrew

+0

Jetzt sehe ich, dass es ein Problem mit der Zeit gibt. Aus irgendeinem Grund ist der maximale Wert der Zeit, die es braucht, 450. Von diesem Punkt nehme immer 350 und springt immer zu dieser Zeit. Die Koordinaten werden korrekt übernommen. Weißt du wie man das löst ?? Vielen Dank. – Andrew

+0

Auch ich sehe in der Markierung mit der Zeit 1056, es dauert die richtige Zeit bis zum letzten Punkt (1356). Der Bereich des nicht erfassten Punktes ist also (350, 1056). – Andrew

0

INITIALIZING
Wenn Sie diese Markierungen in der for Schleife erstellen, fügen Sie sie zu einer map [Datenstruktur], die Sie (leer) vor der Schleife definieren. In der Map werden Marker gespeichert. Ihre Schlüssel - verkettet lat/lng.

  • var initial_markers = {}; //before for loop
  • initial_markers[data.lat+"-"+data.lng] = marker; //after each marker initialization
  • sie Graf, damit Sie wissen, wie viele es sind initial_marker_count, weil Sie nicht Länge Größe eines map [Datenstruktur] erhalten können

NACHWEIS
Wenn Sie auf eine Polylinie geklickt haben, glaube ich nicht, dass Sie genau den Teil der Polylinie erhalten, auf den geklickt wird Sie müssen es selbst bekommen. Die Schritte sind:

  • das von Click-Ereignis
  • Schleife durch die Markierungen
  • koordinieren Get
  • ihre Koordinaten
  • prüfen Nehmen Sie, wenn der angeklickten Punkt auf der Karte auf der Linie zwischen diesen beiden Punkten ist
  • Wenn ist, nehmen Sie die erste dieser beiden Punkte

NACHWEIS Pseudo-Code

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; 
    } 
} 

Der einzige Grund, warum ich sage, dass dieser Pseudo-Code ist, ist, weil ich zwischen zwei Punkten auf die Linie nicht hor wissen finden in Google Maps, wenn Punkt. Und Sie sollten das isPointOnLine() Funktionen schreiben. Abgesehen davon - die Idee ist gegeben. Hoffe, Sie schätzen es.