Skip to content

Instantly share code, notes, and snippets.

@brandon-rhodes
Created August 23, 2012 17:19
Show Gist options
  • Save brandon-rhodes/3438936 to your computer and use it in GitHub Desktop.
Save brandon-rhodes/3438936 to your computer and use it in GitHub Desktop.
Geographically correct alternative to Radarmatic.com's sweepArc() function
/* NOTE: this function requires the Google Maps "geometry" library which
Radarmatic does not currently load. It would need to load Maps with:
http://maps.google.com/maps/api/js?libraries=geometry&sensor=false */
function sweepArc(context, center_x, center_y, radius, width,
start_angle, end_angle) {
/* Special case: if we are being asked to draw the big gray circle
around the current radar site, then draw a big gray circle. */
if (start_angle < 0.1 && end_angle == 2*Math.PI) {
context.beginPath();
context.moveTo(radius + center_x, center_y);
context.arc(center_x, center_y, radius,
start_angle, end_angle, false);
context.lineTo(radius + width + center_x, center_y);
context.arc(center_x, center_y, radius + width,
end_angle, start_angle, true);
context.closePath();
return;
}
/* Otherwise, we compute the lat/lng corners of the real-world
trapezoid that bounds this sweep Arc. */
var thickness = thicknessForZoom(gmap.getZoom());
var wacky_factor_of_two = 2;
var radius_km = radius * wacky_factor_of_two / thickness;
var width_km = width * wacky_factor_of_two / thickness;
var start_heading = 90 + start_angle * 180 / Math.PI;
var end_heading = 90 + end_angle * 180 / Math.PI;
var outer_km = radius_km + width_km;
var sph = google.maps.geometry.spherical;
var ll1 = sph.computeOffset(centre, radius_km * 1e3, start_heading);
var ll2 = sph.computeOffset(centre, outer_km * 1e3, start_heading);
var ll3 = sph.computeOffset(centre, outer_km * 1e3, end_heading);
var ll4 = sph.computeOffset(centre, radius_km * 1e3, end_heading);
/* Figure out the pixel x,y where Google Maps would put each corner. */
var proj = radar_overlay.getProjection();
var dp1 = proj.fromLatLngToDivPixel(ll1);
var dp2 = proj.fromLatLngToDivPixel(ll2);
var dp3 = proj.fromLatLngToDivPixel(ll3);
var dp4 = proj.fromLatLngToDivPixel(ll4);
/* On our HTML5 canvas, the radar station is at the coordinates
(center_x,center_y) instead of at radar_xy, which are its pixel
coordinates on the Google Map; so we shift each corner by that
offset to properly locate the radar image on our canvas. */
var radar_xy = proj.fromLatLngToDivPixel(centre);
var offset_x = center_x - radar_xy.x;
var offset_y = center_y - radar_xy.y;
context.beginPath();
context.moveTo(dp1.x + offset_x, dp1.y + offset_y);
context.lineTo(dp2.x + offset_x, dp2.y + offset_y);
context.lineTo(dp3.x + offset_x, dp3.y + offset_y);
context.lineTo(dp4.x + offset_x, dp4.y + offset_y);
context.closePath();
}
@brandon-rhodes
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment