Created
July 5, 2010 08:21
-
-
Save kulesa/464135 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Helper function to get rid of repeating bindTo calls | |
google.maps.MVCObject::bindProperties: (object, options) -> | |
for key, value of options | |
this.bindTo key, object, value | |
# Add listener for few events at a time. | |
# For example marker.addListener 'dragged', 'distance_changed', updateForm | |
google.maps.MVCObject::addListener: (events..., __func) -> | |
for event in events | |
google.maps.event.addListener this, event, (listener) => __func.call(this) | |
# RadiusWidget is a circle and sizer marker | |
class RadiusWidget extends google.maps.MVCObject | |
constructor: -> | |
circle: new google.maps.Circle { strokeWeight: 2 } | |
this.set 'distance', 50 | |
this.bindTo 'bounds', circle | |
circle.bindProperties this, { | |
center: 'center' | |
map: 'map' | |
radius: 'radius' | |
} | |
this.addSizer_() | |
# magic funciton called on this.set 'distance', N | |
distance_changed: -> | |
this.set 'radius', this.get('distance') * 1000 | |
# Adds sizer marker. When the sizer is dragged, changes circle radius | |
addSizer_: -> | |
sizer: new google.maps.Marker { | |
draggable: true | |
title: 'Drag me!' | |
icon: 'images/resize.png' | |
} | |
sizer.bindProperties this, { | |
map: 'map' | |
position: 'sizer_position' | |
} | |
google.maps.event.addListener sizer, 'drag', (event) => this.setDistance() | |
# Calculates distance between the sizer and center of the cirle and updates circle radius | |
setDistance: -> | |
pos: this.get 'sizer_position' | |
center: this.get 'center' | |
distance: this.distanceBetweenPoints_ center, pos | |
this.set 'distance', distance | |
# Moves sizer marker when the cirle is moved | |
center_changed: -> | |
bounds: this.get 'bounds' | |
if bounds | |
lng: bounds.getNorthEast().lng() | |
position: new google.maps.LatLng this.get('center').lat(), lng | |
this.set 'sizer_position', position | |
# Calculates distance between two given points | |
distanceBetweenPoints_: (p1, p2) -> | |
return 0 unless p1 and p2 | |
R: 6371 | |
dLat: (p2.lat() - p1.lat()) * Math.PI / 180 | |
dLon: (p2.lng() - p1.lng()) * Math.PI / 180 | |
a: Math.sin(dLat / 2) * Math.sin(dLat / 2) + | |
Math.cos(p1.lat() * Math.PI / 180) * Math.cos(p2.lat() * Math.PI / 180) * | |
Math.sin(dLon / 2) * Math.sin(dLon / 2) | |
c: 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)) | |
d: R * c | |
# DistanceWidget is a marker with attached resizable circle. | |
# Use 'position', 'distance' and 'bounds' properties to get information about center, radius and bounds of the cirle. | |
class DistanceWidget extends google.maps.MVCObject | |
constructor: (map) -> | |
this.set 'map', map | |
this.set 'position', map.getCenter() | |
marker: new google.maps.Marker {draggable: true,title: 'Move me'} | |
marker.bindProperties this, { | |
map: 'map' | |
position: 'position' | |
} | |
radiusWidget: new RadiusWidget() | |
radiusWidget.bindProperties this, { | |
map: 'map' | |
center: 'position' | |
} | |
this.bindProperties radiusWidget, { | |
distance: 'distance', | |
bounds: 'bounds' | |
} | |
# Display changed center and radius of the circle | |
displayInfo: -> | |
info: document.getElementById('info') | |
info.innerHTML: 'Position: ' + this.get('position') + ', distance: ' + this.get('distance') | |
# Create map, add distance widget to the map | |
init: -> | |
mapDiv: document.getElementById('map-canvas') | |
latlang: new google.maps.LatLng(37.790234970864, -122.39031314844) | |
map_options: { | |
center: latlang, | |
zoom: 8, | |
mapTypeId: google.maps.MapTypeId.ROADMAP | |
mapTypeControl: false | |
} | |
map: new google.maps.Map mapDiv, map_options | |
distanceWidget: new DistanceWidget map | |
distanceWidget.addListener 'distance_changed', 'position_changed', displayInfo | |
google.maps.event.addDomListener window, 'load', init() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment