Created
November 20, 2012 07:16
-
-
Save ArionHardison/4116535 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
####################################################################################################### | |
############################################## Google maps ########################################## | |
####################################################################################################### | |
class @Gmaps4RailsGoogle extends Gmaps4Rails | |
constructor: -> | |
super | |
#Map settings | |
@map_options = | |
zoom: 10, | |
disableDefaultUI: true | |
disableDoubleClickZoom: false | |
type: "ROADMAP" # HYBRID, ROADMAP, SATELLITE, TERRAIN | |
#markers + info styling | |
@markers_conf = | |
clusterer_gridSize: 50 | |
clusterer_maxZoom: 5 | |
custom_cluster_pictures: null | |
custom_infowindow_class: null | |
@mergeWithDefault("map_options") | |
@mergeWithDefault("markers_conf") | |
@kml_options = | |
clickable: true | |
preserveViewport: false | |
suppressInfoWindows: false | |
#Polygon Styling | |
@polygons_conf = # default style for polygons | |
strokeColor: "#FFAA00" | |
strokeOpacity: 0.8 | |
strokeWeight: 2 | |
fillColor: "#000000" | |
fillOpacity: 0.35 | |
clickable: false | |
#Circle Styling | |
@circles_conf = #default style for circles | |
fillColor: "#00AAFF" | |
fillOpacity: 0.35 | |
strokeColor: "#FFAA00" | |
strokeOpacity: 0.8 | |
strokeWeight: 2 | |
clickable: false | |
zIndex: null | |
#Direction Settings | |
@direction_conf = | |
panel_id: null | |
display_panel: false | |
origin: null | |
destination: null | |
waypoints: [] #[{location: "toulouse,fr", stopover: true}, {location: "Clermont-Ferrand, fr", stopover: true}] | |
optimizeWaypoints: false | |
unitSystem: "METRIC" #IMPERIAL | |
avoidHighways: false | |
avoidTolls: false | |
region: null | |
travelMode: "DRIVING" #WALKING, BICYCLING | |
#//////////////////////////////////////////////////// | |
#/////////////// Basic Objects ////////////// | |
#//////////////////////////////////////////////////// | |
createPoint : (lat, lng) -> | |
return new google.maps.Point(lat, lng) | |
createLatLng : (lat, lng) -> | |
return new google.maps.LatLng(lat, lng) | |
createLatLngBounds : -> | |
return new google.maps.LatLngBounds() | |
createMap : -> | |
defaultOptions = | |
maxZoom: @map_options.maxZoom | |
minZoom: @map_options.minZoom | |
zoom: @map_options.zoom | |
center: @createLatLng(@map_options.center_latitude, @map_options.center_longitude) | |
mapTypeId: google.maps.MapTypeId[@map_options.type] | |
mapTypeControl: @map_options.mapTypeControl | |
disableDefaultUI: @map_options.disableDefaultUI | |
disableDoubleClickZoom: @map_options.disableDoubleClickZoom | |
draggable: @map_options.draggable | |
mergedOptions = @mergeObjectWithDefault @map_options.raw, defaultOptions | |
map = new google.maps.Map document.getElementById(@map_options.id), mergedOptions | |
if navigator.geolocation | |
navigator.geolocation.getCurrentPosition ((position) -> | |
pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude) | |
infowindow = new google.maps.InfoWindow( | |
map: map | |
position: pos | |
) | |
map.setCenter pos | |
), -> | |
handleNoGeolocation true | |
else | |
handleNoGeolocation false | |
return map | |
createMarkerImage : (markerPicture, markerSize, origin, anchor, scaledSize) -> | |
return new google.maps.MarkerImage(markerPicture, markerSize, origin, anchor, scaledSize) | |
createSize : (width, height) -> | |
return new google.maps.Size(width, height) | |
#//////////////////////////////////////////////////// | |
#////////////////////// Markers ///////////////////// | |
#//////////////////////////////////////////////////// | |
createMarker : (args) -> | |
markerLatLng = @createLatLng(args.Lat, args.Lng) | |
#Marker sizes are expressed as a Size of X,Y | |
if args.marker_picture == "" and args.rich_marker == null | |
defaultOptions = {position: markerLatLng, map: @serviceObject, title: args.marker_title, draggable: args.marker_draggable, zIndex: args.zindex} | |
mergedOptions = @mergeObjectWithDefault @markers_conf.raw, defaultOptions | |
return new google.maps.Marker mergedOptions | |
if (args.rich_marker != null) | |
return new RichMarker({ | |
position: markerLatLng | |
map: @serviceObject | |
draggable: args.marker_draggable | |
content: args.rich_marker | |
flat: if args.marker_anchor == null then false else args.marker_anchor[1] | |
anchor: if args.marker_anchor == null then 0 else args.marker_anchor[0] | |
zIndex: args.zindex | |
}) | |
#default behavior | |
#calculate MarkerImage anchor location | |
imageAnchorPosition = @createImageAnchorPosition args.marker_anchor | |
shadowAnchorPosition = @createImageAnchorPosition args.shadow_anchor | |
#create or retrieve existing MarkerImages | |
markerImage = @createOrRetrieveImage(args.marker_picture, args.marker_width, args.marker_height, imageAnchorPosition) | |
shadowImage = @createOrRetrieveImage(args.shadow_picture, args.shadow_width, args.shadow_height, shadowAnchorPosition) | |
defaultOptions = {position: markerLatLng, map: @serviceObject, icon: markerImage, title: args.marker_title, draggable: args.marker_draggable, shadow: shadowImage, zIndex: args.zindex} | |
mergedOptions = @mergeObjectWithDefault @markers_conf.raw, defaultOptions | |
return new google.maps.Marker mergedOptions | |
#checks if obj is included in arr Array and returns the position or false | |
includeMarkerImage : (arr, obj) -> | |
for object, index in arr | |
return index if object.url == obj | |
return false | |
#checks if MarkerImage exists before creating a new one | |
#returns a MarkerImage or false if ever something wrong is passed as argument | |
createOrRetrieveImage : (currentMarkerPicture, markerWidth, markerHeight, imageAnchorPosition) -> | |
return null if (currentMarkerPicture == "" or currentMarkerPicture == null ) | |
test_image_index = @includeMarkerImage(@markerImages, currentMarkerPicture) | |
switch test_image_index | |
when false | |
markerImage = @createMarkerImage(currentMarkerPicture, @createSize(markerWidth, markerHeight), null, imageAnchorPosition, null ) | |
@markerImages.push(markerImage) | |
return markerImage | |
break | |
else | |
return @markerImages[test_image_index] if typeof test_image_index == 'number' | |
return false | |
#clear markers | |
clearMarkers : -> | |
for marker in @markers | |
@clearMarker marker | |
#show and hide markers | |
showMarkers : -> | |
for marker in @markers | |
@showMarker marker | |
hideMarkers : -> | |
for marker in @markers | |
@hideMarker marker | |
clearMarker : (marker) -> | |
marker.serviceObject.setMap(null) | |
showMarker : (marker) -> | |
marker.serviceObject.setVisible(true) | |
hideMarker : (marker) -> | |
marker.serviceObject.setVisible(false) | |
extendBoundsWithMarkers : -> | |
for marker in @markers | |
@boundsObject.extend(marker.serviceObject.position) | |
#//////////////////////////////////////////////////// | |
#/////////////////// Clusterer ////////////////////// | |
#//////////////////////////////////////////////////// | |
createClusterer : (markers_array) -> | |
return new MarkerClusterer( @serviceObject, markers_array, { maxZoom: @markers_conf.clusterer_maxZoom, gridSize: @markers_conf.clusterer_gridSize, styles: @customClusterer() }) | |
clearClusterer : -> | |
@markerClusterer.clearMarkers() | |
#creates clusters | |
clusterize : -> | |
if @markers_conf.do_clustering == true | |
#first clear the existing clusterer if any | |
@clearClusterer() if @markerClusterer != null | |
markers_array = new Array | |
for marker in @markers | |
markers_array.push(marker.serviceObject) | |
@markerClusterer = @createClusterer(markers_array) | |
#//////////////////////////////////////////////////// | |
#/////////////////// INFO WINDOW //////////////////// | |
#//////////////////////////////////////////////////// | |
#// creates infowindows | |
createInfoWindow : (marker_container) -> | |
if typeof(@jsTemplate) == "function" or marker_container.description? | |
marker_container.description = @jsTemplate(marker_container) if typeof(@jsTemplate) == "function" | |
if @markers_conf.custom_infowindow_class != null | |
#creating custom infowindow | |
boxText = document.createElement("div") | |
boxText.setAttribute("class", @markers_conf.custom_infowindow_class) #to customize | |
boxText.innerHTML = marker_container.description | |
marker_container.infowindow = new InfoBox(@infobox(boxText)) | |
currentMap = this | |
google.maps.event.addListener(marker_container.serviceObject, 'click', @openInfoWindow(currentMap, marker_container.infowindow, marker_container.serviceObject)) | |
else | |
#create default infowindow | |
marker_container.infowindow = new google.maps.InfoWindow({content: marker_container.description }) | |
#add the listener associated | |
currentMap = this | |
google.maps.event.addListener(marker_container.serviceObject, 'click', @openInfoWindow(currentMap, marker_container.infowindow, marker_container.serviceObject)) | |
openInfoWindow : (currentMap, infoWindow, marker) -> | |
return -> | |
# Close the latest selected marker before opening the current one. | |
currentMap.visibleInfoWindow.close() if currentMap.visibleInfoWindow != null | |
infoWindow.open(currentMap.serviceObject, marker) | |
currentMap.visibleInfoWindow = infoWindow | |
#//////////////////////////////////////////////////// | |
#///////////////// KML ////////////////// | |
#//////////////////////////////////////////////////// | |
createKmlLayer : (kml) -> | |
kml_options = kml.options || {} | |
kml_options = @mergeObjectWithDefault(kml_options, @kml_options) | |
kml = new google.maps.KmlLayer( kml.url, kml_options) | |
kml.setMap(@serviceObject) | |
return kml | |
#//////////////////////////////////////////////////// | |
#/////////////////// POLYLINES ////////////////////// | |
#//////////////////////////////////////////////////// | |
#creates a single polyline, triggered by create_polylines | |
create_polyline : (polyline) -> | |
polyline_coordinates = [] | |
#2 cases here, either we have a coded array of LatLng or we have an Array of LatLng | |
for element in polyline | |
#if we have a coded array | |
if element.coded_array? | |
decoded_array = new google.maps.geometry.encoding.decodePath(element.coded_array) | |
#loop through every point in the array | |
for point in decoded_array | |
polyline_coordinates.push(point) | |
#or we have an array of latlng | |
else | |
#by convention, a single polyline could be customized in the first array or it uses default values | |
if element == polyline[0] | |
strokeColor = element.strokeColor || @polylines_conf.strokeColor | |
strokeOpacity = element.strokeOpacity || @polylines_conf.strokeOpacity | |
strokeWeight = element.strokeWeight || @polylines_conf.strokeWeight | |
clickable = element.clickable || @polylines_conf.clickable | |
zIndex = element.zIndex || @polylines_conf.zIndex | |
#add latlng if positions provided | |
if element.lat? && element.lng? | |
latlng = @createLatLng(element.lat, element.lng) | |
polyline_coordinates.push(latlng) | |
# Construct the polyline | |
new_poly = new google.maps.Polyline | |
path: polyline_coordinates | |
strokeColor: strokeColor | |
strokeOpacity: strokeOpacity | |
strokeWeight: strokeWeight | |
clickable: clickable | |
zIndex: zIndex | |
#save polyline | |
polyline.serviceObject = new_poly | |
new_poly.setMap(@serviceObject) | |
updateBoundsWithPolylines: ()-> | |
for polyline in @polylines | |
polyline_points = polyline.serviceObject.latLngs.getArray()[0].getArray() | |
for point in polyline_points | |
@boundsObject.extend point | |
#//////////////////////////////////////////////////// | |
#///////////////// KML ////////////////// | |
#//////////////////////////////////////////////////// | |
create_kml : -> | |
for kml in @kml | |
kml.serviceObject = @createKmlLayer kml | |
#//////////////////////////////////////////////////// | |
#/////////////////// Other methods ////////////////// | |
#//////////////////////////////////////////////////// | |
fitBounds : -> | |
@serviceObject.fitBounds(@boundsObject) unless @boundsObject.isEmpty() | |
centerMapOnUser : -> | |
@serviceObject.setCenter(@userLocation) | |
updateBoundsWithPolygons: ()-> | |
for polygon in @polygons | |
polygon_points = polygon.serviceObject.latLngs.getArray()[0].getArray() | |
for point in polygon_points | |
@boundsObject.extend point | |
updateBoundsWithCircles: ()-> | |
for circle in @circles | |
@boundsObject.extend(circle.serviceObject.getBounds().getNorthEast()) | |
@boundsObject.extend(circle.serviceObject.getBounds().getSouthWest()) | |
extendMapBounds: ()-> | |
for bound in @map_options.bounds | |
#create points from bounds provided | |
@boundsObject.extend @createLatLng(bound.lat, bound.lng) | |
adaptMapToBounds:()-> | |
#if autozoom is false, take user info into account | |
if !@map_options.auto_zoom | |
map_center = @boundsObject.getCenter() | |
@map_options.center_latitude = map_center.lat() | |
@map_options.center_longitude = map_center.lng() | |
@serviceObject.setCenter(map_center) | |
else | |
@fitBounds() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment