ESheahan/espolea

View on GitHub
app/assets/javascripts/jquery.geolocateMap.js

Summary

Maintainability
A
2 hrs
Test Coverage
// Generated by CoffeeScript 1.4.0
(function() {
  var GeolocateMap, Marker, version,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

  GeolocateMap = (function() {

    function GeolocateMap($element, settings) {
      var markers_options,
        _this = this;
      this.map = new google.maps.Map($element[0], settings['google_maps']);
      this.markers = Marker.markers_from_objects(this.map, settings['markers'], settings['markers_settings']);
      markers_options = settings['markers_settings'];
      if (markers_options['fit_bounds']) {
        if (this.markers.length >= 2) {
          this.map.fitBounds(Marker.bounds_for_markers(this.markers));
        } else if (this.markers.length === 1) {
          this.map.setCenter(this.markers[0].get_position());
        }
      }
      if (settings['locate_me'] && navigator.geolocation) {
        navigator.geolocation.getCurrentPosition((function(position) {
          _this.marker_me = new Marker(_this.map, {
            lat: position.coords.latitude,
            lng: position.coords.longitude
          }, settings['locate_me_marker']);
          return _this.map.setCenter(_this.marker_me.get_position());
        }), (function(msg) {
          return console.log("geolocation error: " + (JSON.stringify(msg)));
        }));
      }
    }

    return GeolocateMap;

  })();

  (function($) {
    var defaults, methods;
    defaults = {
      google_maps: {
        zoom: 0,
        center: new google.maps.LatLng(0.0, 0.0),
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        scaleControl: true
      },
      markers: [],
      markers_settings: {
        fit_bounds: true,
        draggable: true
      },
      locate_me: false,
      locate_me_marker: {
        draggable: false
      }
    };
    methods = {
      init: function(args) {
        var settings;
        settings = $.extend(true, {}, defaults, args);
        return this.data("geolocate_map", new GeolocateMap(this, settings));
      },
      google_map: function() {
        return this.data("geolocate_map").map;
      },
      google_markers: function() {
        return $(this.data("geolocate_map").markers).map(function(i, marker) {
          return marker.gmark;
        });
      }
    };
    return $.fn.geolocateMap = function(method) {
      if (methods[method]) {
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
      } else if (typeof method === 'object' || !method) {
        return methods.init.apply(this, arguments);
      } else {
        return $.error("Method " + method + " does not exist on jQuery.geolocateMap");
      }
    };
  })(jQuery);

  Marker = (function() {

    function Marker(map, data, settings) {
      this.sync_inputs = __bind(this.sync_inputs, this);

      var infowindow, latitude, longitude, marker_position, pos,
        _this = this;
      latitude = data['lat'];
      longitude = data['lng'];
      pos = new google.maps.LatLng(latitude, longitude);
      marker_position = {
        'position': pos,
        'map': map
      };
      settings = $.extend({}, settings, data, marker_position);
      this.gmark = new google.maps.Marker(settings);
      if (data["infoWindow"]) {
        infowindow = new google.maps.InfoWindow({
          content: data["infoWindow"]
        });
        google.maps.event.addListener(this.gmark, 'click', function() {
          return infowindow.open(map, _this.gmark);
        });
      }
      this.sync_inputs(settings);
    }

    Marker.prototype.get_position = function() {
      return this.gmark.getPosition();
    };

    Marker.prototype.set_position = function(latLng) {
      return this.gmark.setPosition(latLng);
    };

    Marker.markers_from_objects = function(map, markers, settings) {
      return $(markers).map(function(i, e) {
        return new Marker(map, e, settings);
      });
    };

    Marker.bounds_for_markers = function(markers) {
      var bounds;
      bounds = new google.maps.LatLngBounds();
      markers.each(function(i, marker) {
        var latlng;
        if (marker instanceof Marker) {
          latlng = marker.gmark.getPosition();
          return bounds.extend(latlng);
        }
      });
      return bounds;
    };

    Marker.prototype.sync_inputs = function(settings) {
      var $address, $lat, $lng,
        _this = this;
      if (settings['sync_inputs']) {
        $lat = $(settings['sync_inputs']['lat']);
        $lng = $(settings['sync_inputs']['lng']);
        $address = $(settings['sync_inputs']['address']);
        if ($lat) {
          $lat.val(this.get_position().lat());
          $lat.on('change', function() {
            return _this.set_position(new google.maps.LatLng($lat.val(), _this.get_position().lng()));
          });
        }
        if ($lng) {
          $lng.val(this.get_position().lng());
          $lng.on('change', function() {
            return _this.set_position(new google.maps.LatLng(_this.get_position().lat(), $lng.val()));
          });
        }
        if ($address) {
          this.set_address_to_input($address);
          $address.on('change', function() {
            var geocoder;
            geocoder = new google.maps.Geocoder();
            return geocoder.geocode({
              address: $address.val()
            }, function(result, status) {
              var map, position;
              position = result[0].geometry.location;
              map = _this.gmark.getMap();
              map.setCenter(position);
              map.setZoom(15);
              _this.set_position(position);
              return google.maps.event.trigger(_this.gmark, 'dragend');
            });
          });
        }
        return google.maps.event.addListener(this.gmark, 'dragend', function() {
          var map, position;
          map = _this.map;
          position = _this.get_position();
          if ($lat) {
            $lat.val(position.lat());
          }
          if ($lng) {
            $lng.val(position.lng());
          }
          if ($address) {
            return _this.set_address_to_input($address);
          }
        });
      }
    };

    Marker.prototype.set_address_to_input = function($address) {
      var geocoder, latLng;
      geocoder = new google.maps.Geocoder();
      latLng = this.get_position();
      return geocoder.geocode({
        'latLng': latLng
      }, function(results, status) {
        if (status === google.maps.GeocoderStatus.OK) {
          if (results[0]) {
            return $address.val(results[0].formatted_address);
          } else {
            console.log("geocoder not found");
            return $address.val("");
          }
        } else {
          console.log("geocoder fail: " + status);
          return $address.val("");
        }
      });
    };

    return Marker;

  })();

  version = "0.2.1";

}).call(this);