diff --git a/Gemfile b/Gemfile index 30dc238..6db8b7c 100644 --- a/Gemfile +++ b/Gemfile @@ -39,4 +39,5 @@ gem 'rvm' gem 'gmaps4rails' gem 'geocoder' gem 'http_accept_language' +gem 'lodash-rails' diff --git a/Gemfile.lock b/Gemfile.lock index 0051882..1173625 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,6 +66,8 @@ GEM thor (>= 0.14, < 2.0) json (1.8.3) libv8 (3.16.14.11) + lodash-rails (3.10.1) + railties (>= 3.1) mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) @@ -172,6 +174,7 @@ DEPENDENCIES gmaps4rails http_accept_language jquery-rails + lodash-rails rails (= 3.2.22) rspec-rails rvm diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 37c7bfc..b3a551a 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -6,4 +6,6 @@ // //= require jquery //= require jquery_ujs +//= require lodash +//= require gmaps/google //= require_tree . diff --git a/app/assets/javascripts/gmaps4rails/gmaps4rails.base.js.coffee b/app/assets/javascripts/gmaps4rails/gmaps4rails.base.js.coffee deleted file mode 100644 index 10a4034..0000000 --- a/app/assets/javascripts/gmaps4rails/gmaps4rails.base.js.coffee +++ /dev/null @@ -1,474 +0,0 @@ -Gmaps = {} - -Gmaps.loadMaps = -> - #loop through all variable names. - #there should only be maps inside so it trigger their load function - for key, value of Gmaps - searchLoadIncluded = key.search(/load/) - if searchLoadIncluded == -1 - load_function_name = "load_" + key - Gmaps[load_function_name]() - -window.Gmaps = Gmaps - -class @Gmaps4Rails - - constructor: -> - #map config - @map = null #contains the map we're working on - @visibleInfoWindow = null #contains the current opened infowindow - @userLocation = null #contains user's location if geolocalization was performed and successful - - #empty slots - @geolocationFailure = -> false #triggered when geolocation fails. If customized, must be like= function(navigator_handles_geolocation){} where 'navigator_handles_geolocation' is a boolean - @callback = -> false #to let user set a custom callback function - @customClusterer = -> false #to let user set custom clusterer pictures - @infobox = -> false #to let user use custom infoboxes - - @default_map_options = - id: 'map' - draggable: true - detect_location: false # should the browser attempt to use geolocation detection features of HTML5? - center_on_user: false # centers map on the location detected through the browser - center_latitude: 0 - center_longitude: 0 - zoom: 7 - maxZoom: null - minZoom: null - auto_adjust : true # adjust the map to the markers if set to true - auto_zoom: true # zoom given by auto-adjust - bounds: [] # adjust map to these limits. Should be [{"lat": , "lng": }] - raw: {} # raw json to pass additional options - - @default_markers_conf = - #Marker config - title: "" - #MarkerImage config - picture : "" - width: 22 - length: 32 - draggable: false # how to modify: <%= gmaps( "markers" => { "data" => @object.to_gmaps4rails, "options" => { "draggable" => true }}) %> - #clustering config - do_clustering: true # do clustering if set to true - randomize: false # Google maps can't display two markers which have the same coordinates. This randomizer enables to prevent this situation from happening. - max_random_distance: 100 # in meters. Each marker coordinate could be altered by this distance in a random direction - list_container: null # id of the ul that will host links to all markers - offset: 0 # used when adding_markers to an existing map. Because new markers are concated with previous one, offset is here to prevent the existing from being re-created. - raw: {} # raw json to pass additional options - - #Stored variables - @markers = [] # contains all markers. A marker contains the following: {"description": , "longitude": , "title":, "latitude":, "picture": "", "width": "", "length": "", "sidebar": "", "serviceObject": google_marker} - @boundsObject = null # contains current bounds from markers, polylines etc... - @polygons = [] # contains raw data, array of arrays (first element could be a hash containing options) - @polylines = [] # contains raw data, array of arrays (first element could be a hash containing options) - @circles = [] # contains raw data, array of hash - @markerClusterer = null # contains all marker clusterers - @markerImages = [] - - #tnitializes the map - initialize : -> - @map = @createMap() - if (@map_options.detect_location == true or @map_options.center_on_user == true) - @findUserLocation(this) - #resets sidebar if needed - @resetSidebarContent() - - findUserLocation : (map_object) -> - if (navigator.geolocation) - #try to retrieve user's position - positionSuccessful = (position) -> - map_object.userLocation = map_object.createLatLng(position.coords.latitude, position.coords.longitude) - #change map's center to focus on user's geoloc if asked - if(map_object.map_options.center_on_user == true) - map_object.centerMapOnUser() - positionFailure = -> - map_object.geolocationFailure(true) - - navigator.geolocation.getCurrentPosition( positionSuccessful, positionFailure) - else - #failure but the navigator doesn't handle geolocation - map_object.geolocationFailure(false) - - - #//////////////////////////////////////////////////// - #//////////////////// DIRECTIONS //////////////////// - #//////////////////////////////////////////////////// - - create_direction : -> - directionsDisplay = new google.maps.DirectionsRenderer() - directionsService = new google.maps.DirectionsService() - - directionsDisplay.setMap(@map) - #display panel only if required - if @direction_conf.display_panel - directionsDisplay.setPanel(document.getElementById(@direction_conf.panel_id)) - - directionsDisplay.setOptions - suppressMarkers: false - suppressInfoWindows: false - suppressPolylines: false - - request = - origin: @direction_conf.origin - destination: @direction_conf.destination - waypoints: @direction_conf.waypoints - optimizeWaypoints: @direction_conf.optimizeWaypoints - unitSystem: google.maps.DirectionsUnitSystem[@direction_conf.unitSystem] - avoidHighways: @direction_conf.avoidHighways - avoidTolls: @direction_conf.avoidTolls - region: @direction_conf.region - travelMode: google.maps.DirectionsTravelMode[@direction_conf.travelMode] - language: "en" - - directionsService.route request, (response, status) -> - if (status == google.maps.DirectionsStatus.OK) - directionsDisplay.setDirections(response) - - #//////////////////////////////////////////////////// - #///////////////////// CIRCLES ////////////////////// - #//////////////////////////////////////////////////// - - #Loops through all circles - #Loops through all circles and draws them - create_circles : -> - for circle in @circles - @create_circle circle - - create_circle : (circle) -> - #by convention, default style configuration could be integrated in the first element - if circle == @circles[0] - @circles_conf.strokeColor = circle.strokeColor if circle.strokeColor? - @circles_conf.strokeOpacity = circle.strokeOpacity if circle.strokeOpacity? - @circles_conf.strokeWeight = circle.strokeWeight if circle.strokeWeight? - @circles_conf.fillColor = circle.fillColor if circle.fillColor? - @circles_conf.fillOpacity = circle.fillOpacity if circle.fillOpacity? - - if circle.lat? and circle.lng? - # always check if a config is given, if not, use defaults - # NOTE: is there a cleaner way to do this? Maybe a hash merge of some sort? - newCircle = new google.maps.Circle - center: @createLatLng(circle.lat, circle.lng) - strokeColor: circle.strokeColor || @circles_conf.strokeColor - strokeOpacity: circle.strokeOpacity || @circles_conf.strokeOpacity - strokeWeight: circle.strokeWeight || @circles_conf.strokeWeight - fillOpacity: circle.fillOpacity || @circles_conf.fillOpacity - fillColor: circle.fillColor || @circles_conf.fillColor - clickable: circle.clickable || @circles_conf.clickable - zIndex: circle.zIndex || @circles_conf.zIndex - radius: circle.radius - - circle.serviceObject = newCircle - newCircle.setMap(@map) - - # clear circles - clear_circles : -> - for circle in @circles - @clear_circle circle - - clear_circle : (circle) -> - circle.serviceObject.setMap(null) - - hide_circles : -> - for circle in @circles - @hide_circle circle - - hide_circle : (circle) -> - circle.serviceObject.setMap(null) - - show_circles : -> - for circle in @circles - @show_circle @circle - - show_circle : (circle) -> - circle.serviceObject.setMap(@map) - - #//////////////////////////////////////////////////// - #///////////////////// POLYGONS ///////////////////// - #//////////////////////////////////////////////////// - - #polygons is an array of arrays. It loops. - create_polygons : -> - for polygon in @polygons - @create_polygon(polygon) - - #creates a single polygon, triggered by create_polygons - create_polygon : (polygon) -> - polygon_coordinates = [] - - #Polygon points are in an Array, that's why looping is necessary - for point in polygon - latlng = @createLatLng(point.lat, point.lng) - polygon_coordinates.push(latlng) - #first element of an Array could contain specific configuration for this particular polygon. If no config given, use default - if point == polygon[0] - strokeColor = point.strokeColor || @polygons_conf.strokeColor - strokeOpacity = point.strokeOpacity || @polygons_conf.strokeOpacity - strokeWeight = point.strokeWeight || @polygons_conf.strokeWeight - fillColor = point.fillColor || @polygons_conf.fillColor - fillOpacity = point.fillOpacity || @polygons_conf.fillOpacity - - #Construct the polygon - new_poly = new google.maps.Polygon - paths: polygon_coordinates - strokeColor: strokeColor - strokeOpacity: strokeOpacity - strokeWeight: strokeWeight - fillColor: fillColor - fillOpacity: fillOpacity - clickable: false - - #save polygon in list - polygon.serviceObject = new_poly - new_poly.setMap(@map) - - #//////////////////////////////////////////////////// - #/////////////////// POLYLINES ////////////////////// - #//////////////////////////////////////////////////// - - #polylines is an array of arrays. It loops. - create_polylines : -> - for polyline in @polylines - @create_polyline polyline - - #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.length - polyline_coordinates.push(point) - 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 - - #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: false - - #save polyline - polyline.serviceObject = new_poly - new_poly.setMap(@map) - - #//////////////////////////////////////////////////// - #///////////////////// MARKERS ////////////////////// - #//////////////////////////////////////////////////// - - #creates, clusterizes and adjusts map - create_markers : -> - @createServiceMarkersFromMarkers() - @clusterize() - - #create google.maps Markers from data provided by user - createServiceMarkersFromMarkers : -> - for marker, index in @markers - #extract options, test if value passed or use default - Lat = @markers[index].lat - Lng = @markers[index].lng - - #alter coordinates if randomize is true - if @markers_conf.randomize - LatLng = @randomize(Lat, Lng) - #retrieve coordinates from the æarray - Lat = LatLng[0] - Lng = LatLng[1] - - #save object - @markers[index].serviceObject = @createMarker - "marker_picture": if @markers[index].picture then @markers[index].picture else @markers_conf.picture - "marker_width": if @markers[index].width then @markers[index].width else @markers_conf.width - "marker_height": if @markers[index].height then @markers[index].height else @markers_conf.length - "marker_title": if @markers[index].title then @markers[index].title else null - "marker_anchor": if @markers[index].marker_anchor then @markers[index].marker_anchor else null - "shadow_anchor": if @markers[index].shadow_anchor then @markers[index].shadow_anchor else null - "shadow_picture": if @markers[index].shadow_picture then @markers[index].shadow_picture else null - "shadow_width": if @markers[index].shadow_width then @markers[index].shadow_width else null - "shadow_height": if @markers[index].shadow_height then @markers[index].shadow_height else null - "marker_draggable": if @markers[index].draggable then @markers[index].draggable else @markers_conf.draggable - "rich_marker": if @markers[index].rich_marker then @markers[index].rich_marker else null - "Lat": Lat - "Lng": Lng - "index": index - - #add infowindowstuff if enabled - @createInfoWindow(@markers[index]) - #create sidebar if enabled - @createSidebar(@markers[index]) - - @markers_conf.offset = @markers.length - - #creates Image Anchor Position or return null if nothing passed - createImageAnchorPosition : (anchorLocation) -> - if (anchorLocation == null) - return null - else - return @createPoint(anchorLocation[0], anchorLocation[1]) - - - #replace old markers with new markers on an existing map - replaceMarkers : (new_markers) -> - @clearMarkers() - #reset previous markers - @markers = new Array - #reset current bounds - @boundsObject = @createLatLngBounds() - #reset sidebar content if exists - @resetSidebarContent() - #add new markers - @markers_conf.offset = 0 - @addMarkers(new_markers) - - #add new markers to on an existing map - addMarkers : (new_markers) -> - #update the list of markers to take into account - @markers = @markers.concat(new_markers) - #put markers on the map - @create_markers() - @adjustMapToBounds() - - #//////////////////////////////////////////////////// - #///////////////////// SIDEBAR ////////////////////// - #//////////////////////////////////////////////////// - - #//creates sidebar - createSidebar : (marker_container) -> - if (@markers_conf.list_container) - ul = document.getElementById(@markers_conf.list_container) - li = document.createElement('li') - aSel = document.createElement('a') - aSel.href = 'javascript:void(0);' - html = if marker_container.sidebar? then marker_container.sidebar else "Marker" - aSel.innerHTML = html - currentMap = this - aSel.onclick = @sidebar_element_handler(currentMap, marker_container.serviceObject, 'click') - li.appendChild(aSel) - ul.appendChild(li) - - #moves map to marker clicked + open infowindow - sidebar_element_handler : (currentMap, marker, eventType) -> - return () -> - currentMap.map.panTo(marker.position) - google.maps.event.trigger(marker, eventType) - - - resetSidebarContent : -> - if @markers_conf.list_container isnt null - ul = document.getElementById(@markers_conf.list_container) - ul.innerHTML = "" - - #//////////////////////////////////////////////////// - #////////////////// MISCELLANEOUS /////////////////// - #//////////////////////////////////////////////////// - - #to make the map fit the different LatLng points - adjustMapToBounds : -> - - #FIRST_STEP: retrieve all bounds - #create the bounds object only if necessary - if @map_options.auto_adjust or @map_options.bounds isnt null - @boundsObject = @createLatLngBounds() - - #if autodjust is true, must get bounds from markers polylines etc... - if @map_options.auto_adjust - #from markers - @extendBoundsWithMarkers() - - #from polylines: - for polyline in @polylines - polyline_points = polyline.serviceObject.latLngs.getArray()[0].getArray() - for point in polyline_points - @boundsObject.extend point - - #from polygons: - for polygon in @polygons - polygon_points = polygon.serviceObject.latLngs.getArray()[0].getArray() - for point in polygon_points - @boundsObject.extend point - - #from circles - for circle in @circles - @boundsObject.extend(circle.serviceObject.getBounds().getNorthEast()) - @boundsObject.extend(circle.serviceObject.getBounds().getSouthWest()) - - #in every case, I've to take into account the bounds set up by the user - for bound in @map_options.bounds - #create points from bounds provided - #TODO:only works with google maps - bound = @createLatLng(bound.lat, bound.lng) - @boundsObject.extend bound - - #SECOND_STEP: ajust the map to the bounds - if @map_options.auto_adjust or @map_options.bounds.length > 0 - - #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() - @map.setCenter(map_center) - else - @fitBounds() - - #//////////////////////////////////////////////////// - #///////////////// KML ////////////////// - #//////////////////////////////////////////////////// - - create_kml : -> - for kml in @kml - kml.serviceObject = @createKmlLayer kml - - #//////////////////////////////////////////////////// - #///////////////// Basic functions ////////////////// - #///////////////////tests coded////////////////////// - - #//basic function to check existence of a variable - exists : (var_name) -> - return (var_name != "" and typeof var_name != "undefined") - - - #randomize - randomize : (Lat0, Lng0) -> - #distance in meters between 0 and max_random_distance (positive or negative) - dx = @markers_conf.max_random_distance * @random() - dy = @markers_conf.max_random_distance * @random() - Lat = parseFloat(Lat0) + (180/Math.PI)*(dy/6378137) - Lng = parseFloat(Lng0) + ( 90/Math.PI)*(dx/6378137)/Math.cos(Lat0) - return [Lat, Lng] - - mergeObjectWithDefault : (object1, object2) -> - copy_object1 = {} - for key, value of object1 - copy_object1[key] = value - - for key, value of object2 - unless copy_object1[key]? - copy_object1[key] = value - return copy_object1 - - mergeWithDefault : (objectName) -> - default_object = @["default_" + objectName] - object = @[objectName] - @[objectName] = @mergeObjectWithDefault(object, default_object) - return true - - #gives a value between -1 and 1 - random : -> return(Math.random() * 2 -1) \ No newline at end of file diff --git a/app/assets/javascripts/gmaps4rails/gmaps4rails.bing.js.coffee b/app/assets/javascripts/gmaps4rails/gmaps4rails.bing.js.coffee deleted file mode 100644 index b2f0d3b..0000000 --- a/app/assets/javascripts/gmaps4rails/gmaps4rails.bing.js.coffee +++ /dev/null @@ -1,163 +0,0 @@ -###################################################################################################### -############################################## Bing Maps ########################################## -###################################################################################################### - -#// http://wiki.openstreetmap.org/wiki/OpenLayers -#// http://openlayers.org/dev/examples -#//http://docs.openlayers.org/contents.html - -class @Gmaps4RailsBing extends Gmaps4Rails - - constructor: -> - super - @map_options = - type: "road" # aerial, auto, birdseye, collinsBart, mercator, ordnanceSurvey, road - @markers_conf = - infobox: "description" #description or htmlContent - - @mergeWithDefault("map_options") - @mergeWithDefault("markers_conf") - - #//////////////////////////////////////////////////// - #/////////////// Basic Objects ////////////// - #//////////////////////////////////////////////////// - - getMapType: -> - switch @map_options.type - when "road" then return Microsoft.Maps.MapTypeId.road - when "aerial" then return Microsoft.Maps.MapTypeId.aerial - when "auto" then return Microsoft.Maps.MapTypeId.auto - when "birdseye" then return Microsoft.Maps.MapTypeId.birdseye - when "collinsBart" then return Microsoft.Maps.MapTypeId.collinsBart - when "mercator" then return Microsoft.Maps.MapTypeId.mercator - when "ordnanceSurvey" then return Microsoft.Maps.MapTypeId.ordnanceSurvey - else return Microsoft.Maps.MapTypeId.auto - - createPoint: (lat, lng) -> - return new Microsoft.Maps.Point(lat, lng) - - createLatLng:(lat, lng) -> - return new Microsoft.Maps.Location(lat, lng) - - createLatLngBounds: -> - - createMap: -> - return new Microsoft.Maps.Map(document.getElementById(@map_options.id), { - credentials: @map_options.provider_key, - mapTypeId: @getMapType(), - center: @createLatLng(@map_options.center_latitude, @map_options.center_longitude), - zoom: @map_options.zoom - }) - - createSize: (width, height) -> - return new google.maps.Size(width, height) - - #//////////////////////////////////////////////////// - #////////////////////// Markers ///////////////////// - #//////////////////////////////////////////////////// - - createMarker: (args) -> - markerLatLng = @createLatLng(args.Lat, args.Lng) - marker - #// Marker sizes are expressed as a Size of X,Y - if args.marker_picture == "" - marker = new Microsoft.Maps.Pushpin(@createLatLng(args.Lat, args.Lng), { - draggable: args.marker_draggable, - anchor: @createImageAnchorPosition(args.Lat, args.Lng), - text: args.marker_title - } - ); - else - marker = new Microsoft.Maps.Pushpin(@createLatLng(args.Lat, args.Lng), { - draggable: args.marker_draggable, - anchor: @createImageAnchorPosition(args.Lat, args.Lng), - icon: args.marker_picture, - height: args.marker_height, - text: args.marker_title, - width: args.marker_width - } - ); - @addToMap(marker) - return marker - - #// clear markers - clearMarkers: -> - for marker in @markers - @clearMarker marker - - clearMarker: (marker) -> - @removeFromMap(marker.serviceObject) - - #//show and hide markers - showMarkers: -> - for marker in @markers - @showMarker marker - - showMarker: (marker) -> - marker.serviceObject.setOptions({ visible: true }) - - hideMarkers: -> - for marker in @markers - @hideMarker marker - - hideMarker: (marker) -> - marker.serviceObject.setOptions({ visible: false }) - - extendBoundsWithMarkers: -> - locationsArray = [] - for marker in @markers - locationsArray.push(marker.serviceObject.getLocation()) - @boundsObject = Microsoft.Maps.LocationRect.fromLocations(locationsArray) - - #//////////////////////////////////////////////////// - #/////////////////// Clusterer ////////////////////// - #//////////////////////////////////////////////////// - - createClusterer: (markers_array) -> - - clearClusterer: -> - - #//creates clusters - clusterize: -> - - #//////////////////////////////////////////////////// - #/////////////////// INFO WINDOW //////////////////// - #//////////////////////////////////////////////////// - - #// creates infowindows - createInfoWindow: (marker_container) -> - if marker_container.description? - #//create the infowindow - if @markers_conf.infobox == "description" - marker_container.info_window = new Microsoft.Maps.Infobox(marker_container.serviceObject.getLocation(), { description: marker_container.description, visible: false, showCloseButton: true}) - else - marker_container.info_window = new Microsoft.Maps.Infobox(marker_container.serviceObject.getLocation(), { htmlContent: marker_container.description, visible: false}) - - #//add the listener associated - currentMap = this - Microsoft.Maps.Events.addHandler(marker_container.serviceObject, 'click', @openInfoWindow(currentMap, marker_container.info_window)) - @addToMap(marker_container.info_window) - - openInfoWindow: (currentMap, infoWindow) -> - return -> - # Close the latest selected marker before opening the current one. - if currentMap.visibleInfoWindow - currentMap.visibleInfoWindow.setOptions({ visible: false }) - infoWindow.setOptions({ visible:true }) - currentMap.visibleInfoWindow = infoWindow - - #//////////////////////////////////////////////////// - #/////////////////// Other methods ////////////////// - #//////////////////////////////////////////////////// - - fitBounds: -> - @map.setView({bounds: @boundsObject}) - - addToMap: (object)-> - @map.entities.push(object) - - removeFromMap: (object)-> - @map.entities.remove(object) - - centerMapOnUser: -> - @map.setView({ center: @userLocation}) diff --git a/app/assets/javascripts/gmaps4rails/gmaps4rails.googlemaps.js.coffee b/app/assets/javascripts/gmaps4rails/gmaps4rails.googlemaps.js.coffee deleted file mode 100644 index 1ae3fcc..0000000 --- a/app/assets/javascripts/gmaps4rails/gmaps4rails.googlemaps.js.coffee +++ /dev/null @@ -1,259 +0,0 @@ -####################################################################################################### -############################################## Google maps ########################################## -####################################################################################################### - -class @Gmaps4RailsGoogle extends Gmaps4Rails - - constructor: -> - super - #Map settings - @map_options = - disableDefaultUI: false - 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 - - #Polyline Styling - @polylines_conf = #default style for polylines - strokeColor: "#FF0000" - strokeOpacity: 1 - strokeWeight: 2 - - #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 - - return new google.maps.Map document.getElementById(@map_options.id), mergedOptions - - - 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: @map, title: args.marker_title, draggable: args.marker_draggable} - mergedOptions = @mergeObjectWithDefault @markers_conf.raw, defaultOptions - return new google.maps.Marker mergedOptions - - if (args.rich_marker != null) - return new RichMarker({ - position: markerLatLng - map: @map - 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] - }) - - #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: @map, icon: markerImage, title: args.marker_title, draggable: args.marker_draggable, shadow: shadowImage} - 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) -> - console.log 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( @map, 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 @markers_conf.custom_infowindow_class == null && marker_container.description? - #create the 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)) - else #creating custom infowindow - if marker_container.description? - 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)) - - - 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.map, 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(@map) - return kml - - - #//////////////////////////////////////////////////// - #/////////////////// Other methods ////////////////// - #//////////////////////////////////////////////////// - - fitBounds : -> - @map.fitBounds(@boundsObject) - - centerMapOnUser : -> - @map.setCenter(@userLocation) - diff --git a/app/assets/javascripts/gmaps4rails/gmaps4rails.mapquest.js.coffee b/app/assets/javascripts/gmaps4rails/gmaps4rails.mapquest.js.coffee deleted file mode 100644 index 725162c..0000000 --- a/app/assets/javascripts/gmaps4rails/gmaps4rails.mapquest.js.coffee +++ /dev/null @@ -1,134 +0,0 @@ -####################################################################################################### -############################################## Map Quest ############################################# -####################################################################################################### -# http://www.mapquestapi.com/sdk/js/v6.0.0/poi.html - -class @Gmaps4RailsMapquest extends Gmaps4Rails - - constructor: -> - super - #Map settings - @map_options = {type: "map"} #map type (map, sat, hyb) - @markers_conf = {} - @mergeWithDefault "markers_conf" - @mergeWithDefault "map_options" - - #//////////////////////////////////////////////////// - #/////////////// Basic Objects ////////////// - #//////////////////////////////////////////////////// - - createPoint: (lat, lng) -> - return new MQA.Poi({lat: lat, lng: lng}) - - createLatLng: (lat, lng) -> - return {lat: lat, lng: lng} - - createLatLngBounds: -> - - createMap: -> - map = new MQA.TileMap( #// Constructs an instance of MQA.TileMap - document.getElementById(@map_options.id), #//the id of the element on the page you want the map to be added into - @map_options.zoom, #//intial zoom level of the map - {lat: @map_options.center_latitude, lng: @map_options.center_longitude}, - @map_options.type) #//map type (map, sat, hyb) - - MQA.withModule('zoomcontrol3', (-> - map.addControl( - new MQA.LargeZoomControl3(), - new MQA.MapCornerPlacement(MQA.MapCorner.TOP_LEFT) - ) - )) - return map - - createMarkerImage: (markerPicture, markerSize, origin, anchor, scaledSize) -> - - #//////////////////////////////////////////////////// - #////////////////////// Markers ///////////////////// - #//////////////////////////////////////////////////// - - createMarker: (args)-> - marker = new MQA.Poi( {lat: args.Lat, lng: args.Lng} ) - - if args.marker_picture != "" - icon = new MQA.Icon(args.marker_picture, args.marker_height, args.marker_width) - marker.setIcon(icon) - if args.marker_anchor != null - marker.setBias({x: args.marker_anchor[0], y: args.marker_anchor[1]}) - - if args.shadow_picture != "" - icon = new MQA.Icon(args.shadow_picture, args.shadow_height, args.shadow_width) - marker.setShadow(icon) - - if args.shadow_anchor != null - marker.setShadowOffset({x: args.shadow_anchor[0], y: args.shadow_anchor[1]}) - - @addToMap marker - return marker - - - #// 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) -> - @removeFromMap(marker.serviceObject) - - showMarker: (marker) -> - #// marker.serviceObject - - hideMarker: (marker) -> - #// marker.serviceObject - - extendBoundsWithMarkers: -> - if @markers.length >=2 - @boundsObject = new MQA.RectLL(@markers[0].serviceObject.latLng, @markers[1].serviceObject.latLng) - for marker in @markers - @boundsObject.extend marker.serviceObject.latLng - - #//////////////////////////////////////////////////// - #/////////////////// Clusterer ////////////////////// - #//////////////////////////////////////////////////// - - createClusterer: (markers_array) -> - - clearClusterer: -> - - #//creates clusters - clusterize: -> - - #//////////////////////////////////////////////////// - #/////////////////// INFO WINDOW //////////////////// - #//////////////////////////////////////////////////// - - #// creates infowindows - createInfoWindow: (marker_container) -> - marker_container.serviceObject.setInfoTitleHTML(marker_container.description) - #//TODO: how to disable the mouseover display when using setInfoContentHTML? - #//marker_container.serviceObject.setInfoContentHTML(marker_container.description); - - #//////////////////////////////////////////////////// - #/////////////////// Other methods ////////////////// - #//////////////////////////////////////////////////// - - fitBounds: -> - @map.zoomToRect @boundsObject if @markers.length >=2 - @map.setCenter @markers[0].serviceObject.latLng if @markers.length == 1 - - centerMapOnUser: -> - @map.setCenter @userLocation - - addToMap: (object) -> - @map.addShape object - - removeFromMap: (object)-> - @map.removeShape object \ No newline at end of file diff --git a/app/assets/javascripts/gmaps4rails/gmaps4rails.openlayers.js.coffee b/app/assets/javascripts/gmaps4rails/gmaps4rails.openlayers.js.coffee deleted file mode 100644 index 1a68479..0000000 --- a/app/assets/javascripts/gmaps4rails/gmaps4rails.openlayers.js.coffee +++ /dev/null @@ -1,209 +0,0 @@ -####################################################################################################### -############################################## Open Layers ########################################## -####################################################################################################### - -#// http://wiki.openstreetmap.org/wiki/OpenLayers -#// http://openlayers.org/dev/examples -#//http://docs.openlayers.org/contents.html - -class @Gmaps4RailsOpenlayers extends Gmaps4Rails - - constructor: -> - super - @map_options = {} - @mergeWithDefault "map_options" - @markers_conf = {} - @mergeWithDefault "markers_conf" - - @openMarkers = null - @markersLayer = null - @markersControl = null - - #//////////////////////////////////////////////////// - #/////////////// Basic Objects //////////////////// - #//////////////////////////////////////////////////// - - createPoint: (lat, lng)-> - - createLatLng: (lat, lng)-> - return new OpenLayers.LonLat(lng, lat).transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")) # transform from WGS 1984 to Spherical Mercator Projection - - createAnchor: (offset)-> - return null if offset == null - return new OpenLayers.Pixel(offset[0], offset[1]) - - createSize: (width, height)-> - return new OpenLayers.Size(width, height) - - createLatLngBounds: -> - return new OpenLayers.Bounds() - - createMap: -> - #//todo add customization: kind of map and other map options - map = new OpenLayers.Map(@map_options.id) - map.addLayer(new OpenLayers.Layer.OSM()) - map.setCenter(@createLatLng(@map_options.center_latitude, @map_options.center_longitude), #// Center of the map - @map_options.zoom) #// Zoom level - return map - - #//////////////////////////////////////////////////// - #////////////////////// Markers ///////////////////// - #//////////////////////////////////////////////////// - #//http://openlayers.org/dev/examples/marker-shadow.html - createMarker: (args) -> - style_mark = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style['default']) - style_mark.fillOpacity = 1 - - #//creating markers' dedicated layer - if (@markersLayer == null) - @markersLayer = new OpenLayers.Layer.Vector("Markers", null) - @map.addLayer(@markersLayer) - #//TODO move? - @markersLayer.events.register("featureselected", @markersLayer, @onFeatureSelect) - @markersLayer.events.register("featureunselected", @markersLayer, @onFeatureUnselect) - @markersControl = new OpenLayers.Control.SelectFeature(@markersLayer) - @map.addControl(@markersControl) - @markersControl.activate() - #//showing default pic if none available - if args.marker_picture == "" - #style_mark.graphicWidth = 24 - style_mark.graphicHeight = 30 - style_mark.externalGraphic = "http://openlayers.org/dev/img/marker-blue.png" - #//creating custom pic - else - style_mark.graphicWidth = args.marker_width - style_mark.graphicHeight = args.marker_height - style_mark.externalGraphic = args.marker_picture - #//adding anchor if any - if args.marker_anchor != null - style_mark.graphicXOffset = args.marker_anchor[0] - style_mark.graphicYOffset = args.marker_anchor[1] - #//adding shadow if any - if args.shadow_picture != "" - style_mark.backgroundGraphic = args.shadow_picture - style_mark.backgroundWidth = args.shadow_width - style_mark.backgroundHeight = args.shadow_height - #//adding shadow's anchor if any - if args.shadow_anchor != null - style_mark.backgroundXOffset = args.shadow_anchor[0] - style_mark.backgroundYOffset = args.shadow_anchor[1] - - style_mark.graphicTitle = args.title - marker = new OpenLayers.Feature.Vector( - new OpenLayers.Geometry.Point(args.Lng, args.Lat), - null, - style_mark) - #//changing coordinates so that it actually appears on the map! - marker.geometry.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913")) - #//adding layer to the map - @markersLayer.addFeatures([marker]) - - return marker - - #//clear markers - clearMarkers: -> - @clearMarkersLayerIfExists() - @markersLayer = null - @boundsObject = new OpenLayers.Bounds() - - clearMarkersLayerIfExists: -> - @map.removeLayer(@markersLayer) if @markersLayer != null and @map.getLayer(@markersLayer.id) != null - - extendBoundsWithMarkers: -> - for marker in @markers - @boundsObject.extend(@createLatLng(marker.lat,marker.lng)) - - #//////////////////////////////////////////////////// - #/////////////////// Clusterer ////////////////////// - #//////////////////////////////////////////////////// - #//too ugly to be considered valid :( - - createClusterer: (markers_array)-> - options = - pointRadius: "${radius}" - fillColor: "#ffcc66" - fillOpacity: 0.8 - strokeColor: "#cc6633" - strokeWidth: "${width}" - strokeOpacity: 0.8 - funcs = - context: - width: (feature) -> - return (feature.cluster) ? 2 : 1 - radius: (feature) -> - pix = 2 - pix = Math.min(feature.attributes.count, 7) + 2 if feature.cluster - return pix - - style = new OpenLayers.Style options, funcs - - strategy = new OpenLayers.Strategy.Cluster() - - clusters = new OpenLayers.Layer.Vector "Clusters", - strategies: [strategy] - styleMap: new OpenLayers.StyleMap - "default": style - "select": - fillColor: "#8aeeef" - strokeColor: "#32a8a9" - - @clearMarkersLayerIfExists() - @map.addLayer(clusters) - clusters.addFeatures(markers_array) - return clusters - - clusterize: -> - - if @markers_conf.do_clustering == true - #//first clear the existing clusterer if any - if @markerClusterer != null - @clearClusterer() - markers_array = new Array - for marker in markers - markers_array.push(marker.serviceObject) - @markerClusterer = @createClusterer markers_array - - clearClusterer: -> - @map.removeLayer @markerClusterer - - #//////////////////////////////////////////////////// - #/////////////////// INFO WINDOW //////////////////// - #//////////////////////////////////////////////////// - - #// creates infowindows - createInfoWindow: (marker_container) -> - marker_container.serviceObject.infoWindow = marker_container.description if marker_container.description? - - onPopupClose: (evt) -> - #// 'this' is the popup. - @markersControl.unselect @feature - - onFeatureSelect: (evt) -> - feature = evt.feature - popup = new OpenLayers.Popup.FramedCloud("featurePopup", - feature.geometry.getBounds().getCenterLonLat(), - new OpenLayers.Size(300,200), - feature.infoWindow, - null, true, @onPopupClose) - feature.popup = popup - popup.feature = feature - @map.addPopup popup - - onFeatureUnselect: (evt) -> - feature = evt.feature - if feature.popup - #//popup.feature = null; - @map.removePopup feature.popup - feature.popup.destroy() - feature.popup = null - - # #//////////////////////////////////////////////////// - # #/////////////////// Other methods ////////////////// - # #//////////////////////////////////////////////////// - - fitBounds: -> - @map.zoomToExtent(@boundsObject, true) - - centerMapOnUser: -> - @map.setCenter @userLocation - diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index fc25b57..76aa82c 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -4,4 +4,11 @@ * the top of the compiled file, but it's generally better to create a new file per style scope. *= require_self *= require_tree . -*/ \ No newline at end of file +*/ + +.mapContainer { + width: 800px; + height: 400px; + margin-left: auto; + margin-right: auto; +} diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b77f35f..e2288ee 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base protected def guess_best_locale - @requested_locale = request.preferred_language_from(%w{en-US fr-FR}) + @requested_locale = http_accept_language.preferred_language_from(%w{en-US fr-FR}) if @requested_locale I18n.locale = @requested_locale.split('-').first end diff --git a/app/controllers/places_controller.rb b/app/controllers/places_controller.rb index 7e8fa9c..948d257 100644 --- a/app/controllers/places_controller.rb +++ b/app/controllers/places_controller.rb @@ -17,7 +17,10 @@ def geocode else @lat = geocoding_result.latitude @lng = geocoding_result.longitude - @json = '[{"lng":"'+@lng.to_s+'", "lat":"'+@lat.to_s+'"}]' + @hash = Gmaps4rails.build_markers([""]) do |_,marker| + marker.lat @lat + marker.lng @lng + end end end @@ -28,7 +31,10 @@ def antipodes # Compute the antipodes lng = if lng<0 then lng+180 else lng-180 end lat = -lat - @json = '[{"lng":"'+lng.to_s+'", "lat":"'+lat.to_s+'"}]' + @hash = Gmaps4rails.build_markers([""]) do |_,marker| + marker.lat lat + marker.lng lng + end reverse_geocoding_result = Geocoder.search(lat.to_s+","+lng.to_s) @reverse_address = if reverse_geocoding_result.empty? t :address_not_found diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 1a43aef..f4205a0 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -2,6 +2,8 @@ Antipodes + + <%= stylesheet_link_tag "application" %> <%= javascript_include_tag "application" %> <%= csrf_meta_tags %> diff --git a/app/views/places/antipodes.html.erb b/app/views/places/antipodes.html.erb index 1d1c78d..2997c52 100644 --- a/app/views/places/antipodes.html.erb +++ b/app/views/places/antipodes.html.erb @@ -1,5 +1,7 @@

<%=t :other_side %>

-<%= gmaps("markers" => {"data" => @json}, "map_options" => {"processing" => "json", "auto_adjust" => true, "auto_zoom" => false, "zoom" => 10}) %> + +<%= render "shared/map" %> +

<%=t :address %> <%= @reverse_address %>

<%= link_to t(:link_to_start), '/' %>

diff --git a/app/views/places/geocode.html.erb b/app/views/places/geocode.html.erb index aaa5ddd..997fc52 100644 --- a/app/views/places/geocode.html.erb +++ b/app/views/places/geocode.html.erb @@ -1,6 +1,7 @@ -<%= gmaps("markers" => {"data" => @json}, "map_options" => {"processing" => "json", "auto_adjust" => true, "auto_zoom" => false, "zoom" => 10}) %>

<%=t :place_confirmation %>

+<%= render "shared/map" %> + <%= form_tag '/antipodes', :method => 'get' do %> <%= hidden_field_tag(:lat, @lat) %> <%= hidden_field_tag(:lng, @lng) %> diff --git a/app/views/shared/_map.html.erb b/app/views/shared/_map.html.erb new file mode 100644 index 0000000..fe2c760 --- /dev/null +++ b/app/views/shared/_map.html.erb @@ -0,0 +1,16 @@ +
+
+
+ + + diff --git a/db/schema.rb b/db/schema.rb index 10191a1..29bd528 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -14,11 +14,9 @@ ActiveRecord::Schema.define(:version => 20111002143044) do create_table "countries", :force => true do |t| - t.string "name" - t.string "center" - t.text "polygons" - t.datetime "created_at" - t.datetime "updated_at" + t.string "name" + t.string "center" + t.text "polygons" end end