1

I have an agm-polyline with 2 agm-polyline-points. When moving the edge of the line (the middle point) I want the save the new line with 3 points. The problem is, when moving the edge to a new location, the event returns the wrong coordinates / or just coordinates of something else.

    <agm-map [zoom]="zoom" [latitude]="lat" [longitude]="lng" style="height: 500px">
      <agm-polyline [editable]="true" (lineMouseUp)="addEdge($event)">
        <agm-polyline-point 
        *ngFor="let point of points" [latitude]="point.lat" [longitude]="point.lng"></agm-polyline-point>
      </agm-polyline>
    </agm-map>
  lat: number = 32.0795723;
  lng: number = 34.7757089;
  zoom: number = 16;
  @ViewChild('line') polyLine : AgmPolyline;
  points = [
    {lat: 32.0795723, lng: 34.7757089},
    {lat: 32.0780565, lng: 34.7798036}
  ]
  addEdge(event){
    let point = {lat: event.latLng.lat(), lng: event.latLng.lng()};
    if (event.vertex !== undefined) {
      this.points[event.vertex] = point;
    } else if (event.edge !== undefined) {
      this.points.splice(event.edge + 1, 0, point);
    }
    console.log(this.points)
  }

take a look at the stackblitz.

KLTR
  • 1,263
  • 2
  • 14
  • 37

1 Answers1

1

New Answer

My previous answer needed Mercator Projection calculations which is not fun. Looking into it further, there is a polyPathChange event that fires when someone updates the line. You will need to update your agm and rxjs to use this event. I have a working example in this stackblitz. Note that I hide/show the line because the polyPathChange only fires once, so hiding/showing re-initializes the line. so the event fires again. Is there a solution that doesn't require hiding/showing the line? Maybe, but I don't know how to do that.

Old Answer

I know this is a little late, but no formal answer was given to this question.

After playing with this a long time, I finally figured out what is going. The lat/lng on the event that is returning from the (lineMouseUp) is not the node of the line, but it is the new midpoint. So it's not a random number, it's (pointA.lat + pointB.lat)/2. The way to get around this is the following equations before you splice it into the array:

point.lat = (point.lat - this.points[event.edge].lat) * 2 + this.points[event.edge].lat;
point.lng = (point.lng - this.points[event.edge].lng) * 2 + this.points[event.edge].lng;

Note that this may not work in all hemispheres (I don't know, I didn't test that much out), so you may need check if lat/lng are positive/negative and adjust the equation. Here is a working stackblitz

rhavelka
  • 2,283
  • 3
  • 22
  • 36
  • After testing out my code more, it is good for small scale polylines but is super buggy on large scale polylines. so something isn't right – rhavelka Jul 14 '20 at 13:38
  • @KLTR I think I know why it's buggy on large scales. it is scaling for the midpoint to be linear for the current 2D map, but the latitude is not linear on the map, it is non linearly bunched near the equator and spaced out near the poles. Ex: if you draw a line from 0 degrees to 80 degrees, the actual latitude midpoint is 40 but you will get something like 65 because that's what it is on the map's linear scale. – rhavelka Jul 14 '20 at 13:48
  • [wiki](https://en.wikipedia.org/wiki/Mercator_projection) here is a reference of what is going on. I tried finding a different way of capturing the points you want for the line where it doesn't require scary math, but I haven't had any luck. this may be something you need to ask the [github](https://github.com/SebastianM/angular-google-maps) – rhavelka Jul 14 '20 at 14:16
  • Sir, I have the same problem as you, but (polyPathChange) is not reacting at all, is it still working for you? – Massaget Aug 10 '20 at 11:31
  • @Massaget from what I can tell, the stackblitz in my answer is still working – rhavelka Aug 10 '20 at 13:21