imakeitrayne
imakeitrayne

Reputation: 165

google maps api polyline drawing improperly

I have a problem with drawing polylines on a google map.

The map repeats itself, so when I draw a polyline at say (0, -175) to (moving east) (0, 175), it draws a polyline between the two points, but to the west, so the polyline is not from the left to the right as expected, it actually goes across the 180 degree longitude and makes a short polyline. So this leads me to think that the polyline is drawing itself using the shortest path between the two points, but I thought this was only if geodesic is set to true, and I don't even have it set as true so it should by default be false.

So my question is how can I fix this?

Upvotes: 1

Views: 1491

Answers (1)

geocodezip
geocodezip

Reputation: 161334

Add a point to the middle of the polyline.

example

screen shot of result

code snippet (blue line is original path, updated line is red, blue marker at the additional point):

var map = null;
var bounds = null;
var infowindow = new google.maps.InfoWindow({
  size: new google.maps.Size(150, 50)
});

function initialize() {
  var myOptions = {
    zoom: 10,
    center: new google.maps.LatLng(-33.9, 151.2),
    mapTypeControl: true,
    mapTypeControlOptions: {
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
    },
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  map = new google.maps.Map(document.getElementById("map_canvas"),
    myOptions);

  bounds = new google.maps.LatLngBounds();

  google.maps.event.addListener(map, 'click', function() {
    infowindow.close();
  });

  var startPoint = new google.maps.LatLng(40.0, 175.0);
  bounds.extend(startPoint);

  var endPoint = new google.maps.LatLng(42.00547, -122.61535);
  bounds.extend(endPoint);

  var normalPolyline = new google.maps.Polyline({
    path: [startPoint, endPoint],
    strokeColor: "#0000FF",
    strokeOpacity: 0.5,
    strokeWeight: 2,
    map: map
  });


  createMarker(startPoint, "start: " + startPoint.toUrlValue(6) + "<br><a href='javascript:map.setCenter(new google.maps.LatLng(" + startPoint.toUrlValue(6) + "));map.setZoom(20);'>zoom in</a> - <a href='javascript:map.fitBounds(bounds);'>zoom out</a>", "start");

  createMarker(endPoint, "end: " + endPoint.toUrlValue(6) + "<br><a href='javascript:map.setCenter(new google.maps.LatLng(" + endPoint.toUrlValue(6) + "));map.setZoom(20);'>zoom in</a> - <a href='javascript:map.fitBounds(bounds);'>zoom out</a>", "end");

  var geodesicPoly = new google.maps.Polyline({
    path: [startPoint, endPoint],
    strokeColor: "#00FF00",
    strokeOpacity: 0.5,
    strokeWeight: 2,
    geodesic: true,
    map: map
  });



  google.maps.event.addListener(map, 'projection_changed', function() {
    // second part of initialization, after projection has loaded
    var normalCenterPoint = normalPolyline.GetPointAtDistance(google.maps.geometry.spherical.computeDistanceBetween(startPoint, endPoint) / 2);
    createMarker(normalCenterPoint, "center of normal polyline<br>" + normalCenterPoint.toUrlValue(6) + "<br><a href='javascript:map.setCenter(new google.maps.LatLng(" + normalCenterPoint.toUrlValue(6) + "));map.setZoom(20);'>zoom in</a> - <a href='javascript:map.fitBounds(bounds);'>zoom out</a>", "middle", "http://maps.google.com/mapfiles/ms/icons/blue.png");

    var normalPolylineCenter = new google.maps.Polyline({
      path: [startPoint, normalCenterPoint, endPoint],
      strokeColor: "#FF0000",
      strokeOpacity: 0.5,
      strokeWeight: 2,
      map: map
    });
    map.fitBounds(bounds);


  });

  map.fitBounds(bounds);
}

function createMarker(latlng, html, title, icon) {
    var contentString = html;
    var marker = new google.maps.Marker({
      position: latlng,
      map: map,
      icon: icon,
      title: title,
      zIndex: Math.round(latlng.lat() * -100000) << 5
    });
    bounds.extend(latlng);
    google.maps.event.addListener(marker, 'click', function() {
      infowindow.setContent(contentString);
      infowindow.open(map, marker);
    });
  }

  // from the epoly library, originally written by Mike Williams
  // http://econym.org.uk/gmap/epoly.htm 
  // updated to API v3 by Larry Ross (geocodezip) 
  // === A method which returns a GLatLng of a point a given distance along the path ===
  // === Returns null if the path is shorter than the specified distance ===
google.maps.Polyline.prototype.GetPointAtDistance = function(metres) {
  // some awkwarpecial cases
  if (metres == 0) return this.getPath().getAt(0);
  if (metres < 0) return null;
  if (this.getPath().getLength() < 2) return null;
  var dist = 0;
  var olddist = 0;
  for (var i = 1;
    (i < this.getPath().getLength() && dist < metres); i++) {
    olddist = dist;
    dist += google.maps.geometry.spherical.computeDistanceBetween(this.getPath().getAt(i), this.getPath().getAt(i - 1));
  }
  if (dist < metres) {
    return null;
  }
  var projection = this.getMap().getProjection();
  if (!projection) {
    alert("no projection");
    return;
  }
  // Project 
  var p1 = projection.fromLatLngToPoint(this.getPath().getAt(i - 2));
  var p2 = projection.fromLatLngToPoint(this.getPath().getAt(i - 1));
  var m = (metres - olddist) / (dist - olddist);
  // alert("p1="+p1+" p2="+p2+" m="+m);
  // Unproject 
  return projection.fromPointToLatLng(new google.maps.Point(p1.x + (p2.x - p1.x) * m, p1.y + (p2.y - p1.y) * m));
}

google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map_canvas {
  width: 100%;
  height: 100%;
  padding: 0px;
  margin: 0px;
}
<script type="text/javascript" src="https://maps.google.com/maps/api/js?libraries=geometry"></script>

<div id="map_canvas" style="width:100%; height:100%"></div>

Upvotes: 4

Related Questions