mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-11 23:17:48 +00:00
Merge branch 'migrate_ent_types' into bugfix
Conflicts: app/models/spree/ability_decorator.rb
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
angular.module("admin.enterprises")
|
||||
# Populate Enterprise.enterprise with enterprise json array from the page.
|
||||
.factory 'Enterprise', (enterprise) ->
|
||||
new class Enterprise
|
||||
enterprise: enterprise
|
||||
enterprise: enterprise
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
Darkswarm.controller "HubsCtrl", ($scope, Hubs, Search, $document, $rootScope, HashNavigation, FilterSelectorsService, MapModal) ->
|
||||
$scope.Hubs = Hubs
|
||||
$scope.hubs = Hubs.visible
|
||||
Darkswarm.controller "EnterprisesCtrl", ($scope, Enterprises, Search, $document, $rootScope, HashNavigation, FilterSelectorsService, EnterpriseModal) ->
|
||||
$scope.Enterprises = Enterprises
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.query = Search.search()
|
||||
$scope.openModal = EnterpriseModal.open
|
||||
$scope.activeTaxons = []
|
||||
$scope.show_profiles = false
|
||||
$scope.openModal = MapModal.open
|
||||
$scope.filtersActive = false
|
||||
|
||||
$scope.$watch "query", (query)->
|
||||
Search.search query
|
||||
@@ -1,14 +0,0 @@
|
||||
Darkswarm.controller "ProducersCtrl", ($scope, Producers, $filter, FilterSelectorsService, Search, MapModal) ->
|
||||
$scope.Producers = Producers
|
||||
$scope.totalActive = FilterSelectorsService.totalActive
|
||||
$scope.clearAll = FilterSelectorsService.clearAll
|
||||
$scope.filterText = FilterSelectorsService.filterText
|
||||
$scope.FilterSelectorsService = FilterSelectorsService
|
||||
$scope.filtersActive = false
|
||||
$scope.activeTaxons = []
|
||||
$scope.query = Search.search()
|
||||
$scope.show_profiles = false
|
||||
$scope.openModal = MapModal.open
|
||||
|
||||
$scope.$watch "query", (query)->
|
||||
Search.search query
|
||||
@@ -1,3 +1,4 @@
|
||||
Darkswarm.controller "ProducersTabCtrl", ($scope, CurrentHub, Enterprises) ->
|
||||
# Injecting Enterprises so CurrentHub.producers is dereferenced
|
||||
Darkswarm.controller "ProducersTabCtrl", ($scope, CurrentHub, Enterprises, EnterpriseModal) ->
|
||||
# Injecting Enterprises so CurrentHub.producers is dereferenced.
|
||||
# We should probably dereference here instead and separate out CurrentHub dereferencing from the Enterprise factory.
|
||||
$scope.CurrentHub = CurrentHub
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
Darkswarm.controller "TabsCtrl", ($scope, $rootScope, $location, OrderCycle) ->
|
||||
# Return active if supplied path matches url hash path.
|
||||
$scope.active = (path)->
|
||||
if !OrderCycle.selected() and $location.hash() == "" and path == "about"
|
||||
true
|
||||
else
|
||||
$location.hash() == path
|
||||
$location.hash() == path
|
||||
|
||||
|
||||
$scope.tabs = ["contact", "about", "groups", "producers"]
|
||||
for tab in $scope.tabs
|
||||
$scope[tab] =
|
||||
path: tab
|
||||
|
||||
$scope.select = (tab)->
|
||||
if $scope.active(tab.path)
|
||||
# Toggle tab selected status by setting the url hash path.
|
||||
$scope.select = (path)->
|
||||
if $scope.active(path)
|
||||
$location.hash ""
|
||||
else
|
||||
$location.hash tab.path
|
||||
$location.hash path
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Darkswarm.directive "producerModal", ($modal)->
|
||||
Darkswarm.directive "enterpriseModal", ($modal)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
template: "<a ng-transclude></a>"
|
||||
@@ -6,5 +6,4 @@ Darkswarm.directive "producerModal", ($modal)->
|
||||
link: (scope, elem, attrs, ctrl)->
|
||||
elem.on "click", (ev)=>
|
||||
ev.stopPropagation()
|
||||
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'producer_modal.html', scope: scope)
|
||||
|
||||
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'enterprise_modal.html', scope: scope)
|
||||
@@ -1,8 +0,0 @@
|
||||
Darkswarm.directive "hubModal", ($modal)->
|
||||
restrict: 'E'
|
||||
replace: true
|
||||
template: "<a>{{enterprise.name}}</a>"
|
||||
link: (scope, elem, attrs, ctrl)->
|
||||
elem.on "click", (ev)=>
|
||||
ev.stopPropagation()
|
||||
scope.modalInstance = $modal.open(controller: ctrl, templateUrl: 'hub_modal.html', scope: scope)
|
||||
@@ -1,4 +1,5 @@
|
||||
Darkswarm.filter "capitalize", ->
|
||||
# Convert to basic sentence case.
|
||||
(input, scope) ->
|
||||
input = input.toLowerCase() if input?
|
||||
input = input.toLowerCase() if input?
|
||||
input.substring(0, 1).toUpperCase() + input.substring(1)
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
Darkswarm.filter 'hubs', (Matcher)->
|
||||
(hubs, text) ->
|
||||
hubs ||= []
|
||||
text ?= ""
|
||||
|
||||
hubs.filter (hub)=>
|
||||
Matcher.match [
|
||||
hub.name, hub.address.zipcode, hub.address.city, hub.address.state
|
||||
], text
|
||||
@@ -1,6 +0,0 @@
|
||||
Darkswarm.filter 'filterProducers', (hubsFilter)->
|
||||
(producers, text) ->
|
||||
producers ||= []
|
||||
text ?= ""
|
||||
hubsFilter(producers, text)
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
# Convert number to string currency using injected currency configuration.
|
||||
#
|
||||
# @requires currencyConfig json - /app/serializers/api/currency_config_serializer.rb
|
||||
# @return: string
|
||||
Darkswarm.filter "localizeCurrency", (currencyConfig)->
|
||||
# Convert number to string currency using injected currency configuration.
|
||||
(amount) ->
|
||||
# Set country code (eg. "US").
|
||||
currency_code = if currencyConfig.display_currency then " " + currencyConfig.currency else ""
|
||||
# Set decimal points, 2 or 0 if hide_cents.
|
||||
decimals = if currencyConfig.hide_cents == "true" then 0 else 2
|
||||
# We need to use parseFloat before toFixed as the amount should be a passed in as a string.
|
||||
# We need to use parseFloat before toFixed as the amount should come in as a string.
|
||||
amount_fixed = parseFloat(amount).toFixed(decimals)
|
||||
|
||||
# Build the final price string.
|
||||
# Build the final price string. TODO use spree decimal point and spacer character settings.
|
||||
if currencyConfig.symbol_position == 'before'
|
||||
currencyConfig.symbol + amount_fixed + currency_code
|
||||
else
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
Darkswarm.filter 'searchEnterprises', (Matcher)->
|
||||
# Search multiple fields of enterprises for matching text fragment.
|
||||
(enterprises, text) ->
|
||||
enterprises ||= []
|
||||
text ?= ""
|
||||
|
||||
enterprises.filter (enterprise)=>
|
||||
Matcher.match [
|
||||
enterprise.name, enterprise.address.zipcode, enterprise.address.city, enterprise.address.state
|
||||
], text
|
||||
@@ -0,0 +1,8 @@
|
||||
Darkswarm.filter 'showHubProfiles', ()->
|
||||
# Filter hub_profile enterprises in or out.
|
||||
(enterprises, show_profiles) ->
|
||||
enterprises ||= []
|
||||
show_profiles ?= false
|
||||
|
||||
enterprises.filter (enterprise)=>
|
||||
show_profiles or enterprise.is_distributor
|
||||
@@ -1,7 +0,0 @@
|
||||
Darkswarm.filter 'showProfiles', ()->
|
||||
(enterprises, show_profiles) ->
|
||||
enterprises ||= []
|
||||
show_profiles ?= true
|
||||
|
||||
enterprises.filter (enterprise)=>
|
||||
show_profiles or enterprise.has_shopfront
|
||||
@@ -1,13 +1,16 @@
|
||||
Darkswarm.filter 'taxons', (Matcher)->
|
||||
# Filter anything that responds to object.taxons, and/or object.primary_taxon
|
||||
Darkswarm.filter 'taxons', ()->
|
||||
# Filter anything that responds to object.taxons, object.supplied_taxon or object.primary_taxon.
|
||||
(objects, ids) ->
|
||||
objects ||= []
|
||||
ids ?= []
|
||||
if ids.length == 0
|
||||
# No taxons selected, pass all objects through.
|
||||
objects
|
||||
else
|
||||
objects.filter (obj)->
|
||||
taxons = obj.taxons
|
||||
taxons.concat obj.supplied_taxons if obj.supplied_taxons
|
||||
# Combine object taxons with supplied taxons, if they exist.
|
||||
taxons = taxons.concat obj.supplied_taxons if obj.supplied_taxons
|
||||
# Match primary taxon if it exists, then taxon array.
|
||||
obj.primary_taxon?.id in ids || taxons.some (taxon)->
|
||||
taxon.id in ids
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
Darkswarm.factory 'CurrentHub', ($location, $filter, currentHub) ->
|
||||
Darkswarm.factory 'CurrentHub', (currentHub) ->
|
||||
# Populate CurrentHub.hub from json in page. This is probably redundant now.
|
||||
new class CurrentHub
|
||||
hub: currentHub
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
Darkswarm.factory 'CurrentOrder', (currentOrder) ->
|
||||
# Populate Currentorder.order from json in page. This is probably redundant now.
|
||||
new class CurrentOrder
|
||||
order: currentOrder
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
Darkswarm.factory "EnterpriseModal", ($modal, $rootScope)->
|
||||
# Build a modal popup for an enterprise.
|
||||
new class EnterpriseModal
|
||||
open: (enterprise)->
|
||||
scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise
|
||||
|
||||
scope.enterprise = enterprise
|
||||
$modal.open(templateUrl: "enterprise_modal.html", scope: scope)
|
||||
@@ -1,13 +1,21 @@
|
||||
Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer)->
|
||||
Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer, visibleFilter)->
|
||||
new class Enterprises
|
||||
enterprises_by_id: {} # id/object pairs for lookup
|
||||
enterprises_by_id: {}
|
||||
constructor: ->
|
||||
# Populate Enterprises.enterprises from json in page.
|
||||
@enterprises = enterprises
|
||||
# Map enterprises to id/object pairs for lookup.
|
||||
for enterprise in enterprises
|
||||
@enterprises_by_id[enterprise.id] = enterprise
|
||||
# Replace enterprise and taxons ids with actual objects.
|
||||
@dereferenceEnterprises()
|
||||
@dereferenceTaxons()
|
||||
|
||||
@visible_enterprises = visibleFilter @enterprises
|
||||
@producers = @visible_enterprises.filter (enterprise)->
|
||||
enterprise.category in ["producer_hub", "producer_shop", "producer"]
|
||||
@hubs = @visible_enterprises.filter (enterprise)->
|
||||
enterprise.category in ["hub", "hub_profile", "producer_hub", "producer_shop"]
|
||||
|
||||
dereferenceEnterprises: ->
|
||||
if CurrentHub.hub?.id
|
||||
CurrentHub.hub = @enterprises_by_id[CurrentHub.hub.id]
|
||||
@@ -16,6 +24,7 @@ Darkswarm.factory 'Enterprises', (enterprises, CurrentHub, Taxons, Dereferencer)
|
||||
Dereferencer.dereference enterprise.producers, @enterprises_by_id
|
||||
|
||||
dereferenceTaxons: ->
|
||||
for enterprise in @enterprises
|
||||
for enterprise in @enterprises
|
||||
Dereferencer.dereference enterprise.taxons, Taxons.taxons_by_id
|
||||
Dereferencer.dereference enterprise.supplied_taxons, Taxons.taxons_by_id
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
Darkswarm.factory 'Hubs', ($filter, Enterprises, visibleFilter) ->
|
||||
new class Hubs
|
||||
constructor: ->
|
||||
@hubs = @order Enterprises.enterprises.filter (hub)->
|
||||
hub.has_hub_listing
|
||||
@visible = visibleFilter @hubs
|
||||
|
||||
order: (hubs)->
|
||||
$filter('orderBy')(hubs, ['-active', '+orders_close_at'])
|
||||
@@ -1,7 +1,7 @@
|
||||
Darkswarm.factory "OfnMap", (Enterprises, MapModal, visibleFilter)->
|
||||
Darkswarm.factory "OfnMap", (Enterprises, EnterpriseModal, visibleFilter)->
|
||||
new class OfnMap
|
||||
constructor: ->
|
||||
@enterprises = (@extend(enterprise) for enterprise in visibleFilter(Enterprises.enterprises))
|
||||
@enterprises = (@extend(enterprise) for enterprise in visibleFilter(Enterprises.enterprises))
|
||||
|
||||
|
||||
# Adding methods to each enterprise
|
||||
@@ -14,4 +14,4 @@ Darkswarm.factory "OfnMap", (Enterprises, MapModal, visibleFilter)->
|
||||
icon: enterprise.icon
|
||||
id: enterprise.id
|
||||
reveal: =>
|
||||
MapModal.open enterprise
|
||||
EnterpriseModal.open enterprise
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
Darkswarm.factory "MapModal", ($modal, $rootScope)->
|
||||
new class MapModal
|
||||
open: (enterprise)->
|
||||
scope = $rootScope.$new(true) # Spawn an isolate to contain the enterprise
|
||||
|
||||
scope.enterprise = enterprise
|
||||
if enterprise.is_distributor
|
||||
scope.hub = enterprise
|
||||
$modal.open(templateUrl: "hub_modal.html", scope: scope)
|
||||
else
|
||||
scope.producer = enterprise
|
||||
$modal.open(templateUrl: "map_modal_producer.html", scope: scope)
|
||||
@@ -1,6 +1,7 @@
|
||||
Darkswarm.factory "Matcher", ->
|
||||
new class Matcher
|
||||
match: (properties, text)->
|
||||
properties.some (prop)->
|
||||
prop ||= ""
|
||||
prop.toLowerCase().indexOf(text.toLowerCase()) != -1
|
||||
# Match text fragment in an array of strings.
|
||||
new class Matcher
|
||||
match: (properties, text)->
|
||||
properties.some (prop)->
|
||||
prop ||= ""
|
||||
prop.toLowerCase().indexOf(text.toLowerCase()) != -1
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
Darkswarm.factory 'Producers', (Enterprises, visibleFilter) ->
|
||||
new class Producers
|
||||
constructor: ->
|
||||
@producers = Enterprises.enterprises.filter (enterprise)->
|
||||
enterprise.is_primary_producer
|
||||
@visible = visibleFilter @producers
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
Darkswarm.factory "Taxons", (taxons)->
|
||||
new class Taxons
|
||||
taxons: taxons
|
||||
# Populate Taxons.taxons from json in page.
|
||||
taxons: taxons
|
||||
taxons_by_id: {}
|
||||
constructor: ->
|
||||
# Map taxons to id/object pairs for lookup.
|
||||
for taxon in @taxons
|
||||
@taxons_by_id[taxon.id] = taxon
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ Darkswarm.factory 'Variants', ->
|
||||
@variants[variant.id] ||= @extend variant
|
||||
|
||||
extend: (variant)->
|
||||
# Add totalPrice method to calculate line item total. This should be on a line item!
|
||||
variant.totalPrice = ->
|
||||
variant.price_with_fees * variant.line_item.quantity
|
||||
variant.basePricePercentage = Math.round(variant.price / variant.price_with_fees * 100)
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// This is a manifest file that'll be compiled into including all the files listed below.
|
||||
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
|
||||
// be included in the compiled file accessible from http://example.com/assets/application.js
|
||||
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||
// the compiled file.
|
||||
//
|
||||
|
||||
//= require jquery
|
||||
//= require jquery_ujs
|
||||
//= require jquery-ui
|
||||
//= require spin
|
||||
//= require foundation
|
||||
//= require_tree .
|
||||
//
|
||||
|
||||
// Hacky fix for issue - http://foundation.zurb.com/forum/posts/2112-foundation-5100-syntax-error-in-js
|
||||
Foundation.set_namespace = function() {};
|
||||
$(function(){ $(document).foundation(); });
|
||||
@@ -1,444 +0,0 @@
|
||||
Gmaps = {}
|
||||
|
||||
Gmaps.triggerOldOnload = ->
|
||||
Gmaps.oldOnload() if typeof(Gmaps.oldOnload) == 'function'
|
||||
|
||||
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 #DEPRECATED: will still contain a copy of serviceObject below as transition
|
||||
@serviceObject = 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
|
||||
@geolocationSuccess = -> false #triggered when geolocation succeeds. Can be customized.
|
||||
@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
|
||||
@jsTemplate = false #to let user create infowindows client side
|
||||
|
||||
@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: false # 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 = []
|
||||
|
||||
#Polyline Styling
|
||||
@polylines_conf = #default style for polylines
|
||||
strokeColor: "#FF0000"
|
||||
strokeOpacity: 1
|
||||
strokeWeight: 2
|
||||
clickable: false
|
||||
zIndex: null
|
||||
|
||||
#tnitializes the map
|
||||
initialize : ->
|
||||
@serviceObject = @createMap()
|
||||
@map = @serviceObject #beware, soon deprecated
|
||||
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()
|
||||
map_object.geolocationSuccess()
|
||||
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(@serviceObject)
|
||||
#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(@serviceObject)
|
||||
|
||||
# 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(@serviceObject)
|
||||
|
||||
#////////////////////////////////////////////////////
|
||||
#///////////////////// 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
|
||||
clickable = point.clickable || @polygons_conf.clickable
|
||||
|
||||
#Construct the polygon
|
||||
new_poly = new google.maps.Polygon
|
||||
paths: polygon_coordinates
|
||||
strokeColor: strokeColor
|
||||
strokeOpacity: strokeOpacity
|
||||
strokeWeight: strokeWeight
|
||||
fillColor: fillColor
|
||||
fillOpacity: fillOpacity
|
||||
clickable: clickable
|
||||
map: @serviceObject
|
||||
|
||||
#save polygon in list
|
||||
polygon.serviceObject = new_poly
|
||||
|
||||
|
||||
|
||||
#////////////////////////////////////////////////////
|
||||
#///////////////////// 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
|
||||
if not @markers[index].serviceObject?
|
||||
#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
|
||||
"zindex": if @markers[index].zindex then @markers[index].zindex 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, adjustBounds = true) ->
|
||||
@clearMarkers()
|
||||
#reset previous markers
|
||||
@markers = new Array
|
||||
#reset current bounds
|
||||
@boundsObject = @createLatLngBounds() if adjustBounds
|
||||
#reset sidebar content if exists
|
||||
@resetSidebarContent()
|
||||
#add new markers
|
||||
@markers_conf.offset = 0
|
||||
@addMarkers(new_markers, adjustBounds)
|
||||
|
||||
#add new markers to on an existing map
|
||||
addMarkers : (new_markers, adjustBounds = true) ->
|
||||
#update the list of markers to take into account
|
||||
@markers = @markers.concat(new_markers)
|
||||
#put markers on the map
|
||||
@create_markers()
|
||||
@adjustMapToBounds() if adjustBounds
|
||||
|
||||
#////////////////////////////////////////////////////
|
||||
#///////////////////// 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:
|
||||
@updateBoundsWithPolylines()
|
||||
|
||||
#from polygons:
|
||||
@updateBoundsWithPolygons()
|
||||
|
||||
#from circles
|
||||
@updateBoundsWithCircles()
|
||||
|
||||
#in every case, I've to take into account the bounds set up by the user
|
||||
@extendMapBounds()
|
||||
|
||||
#SECOND_STEP: ajust the map to the bounds
|
||||
@adaptMapToBounds()
|
||||
|
||||
#////////////////////////////////////////////////////
|
||||
#/////////////////// POLYLINES //////////////////////
|
||||
#////////////////////////////////////////////////////
|
||||
|
||||
#replace old markers with new markers on an existing map
|
||||
replacePolylines : (new_polylines) ->
|
||||
#reset previous polylines and kill them from map
|
||||
@destroy_polylines()
|
||||
#set new polylines
|
||||
@polylines = new_polylines
|
||||
#create
|
||||
@create_polylines()
|
||||
#.... and adjust map boundaries
|
||||
@adjustMapToBounds()
|
||||
|
||||
destroy_polylines : ->
|
||||
for polyline in @polylines
|
||||
#delete polylines from map
|
||||
polyline.serviceObject.setMap(null)
|
||||
#empty array
|
||||
@polylines = []
|
||||
|
||||
#polylines is an array of arrays. It loops.
|
||||
create_polylines : ->
|
||||
for polyline in @polylines
|
||||
@create_polyline polyline
|
||||
|
||||
#////////////////////////////////////////////////////
|
||||
#///////////////// 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)
|
||||
@@ -1,174 +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: ->
|
||||
@serviceObject.setView({bounds: @boundsObject})
|
||||
|
||||
addToMap: (object)->
|
||||
@serviceObject.entities.push(object)
|
||||
|
||||
removeFromMap: (object)->
|
||||
@serviceObject.entities.remove(object)
|
||||
|
||||
centerMapOnUser: ->
|
||||
@serviceObject.setView({ center: @userLocation})
|
||||
|
||||
updateBoundsWithPolylines: ()->
|
||||
|
||||
updateBoundsWithPolygons: ()->
|
||||
|
||||
updateBoundsWithCircles: ()->
|
||||
|
||||
extendMapBounds :->
|
||||
|
||||
adaptMapToBounds: ->
|
||||
@fitBounds()
|
||||
@@ -1,339 +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
|
||||
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
|
||||
|
||||
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: @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()
|
||||
@@ -1,145 +0,0 @@
|
||||
#######################################################################################################
|
||||
############################################## Map Quest #############################################
|
||||
#######################################################################################################
|
||||
# http://developer.mapquest.com/web/documentation/sdk/javascript/v7.0/api/MQA.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: ->
|
||||
@serviceObject.zoomToRect @boundsObject if @markers.length >=2
|
||||
@serviceObject.setCenter @markers[0].serviceObject.latLng if @markers.length == 1
|
||||
|
||||
centerMapOnUser: ->
|
||||
@serviceObject.setCenter @userLocation
|
||||
|
||||
addToMap: (object) ->
|
||||
@serviceObject.addShape object
|
||||
|
||||
removeFromMap: (object)->
|
||||
@serviceObject.removeShape object
|
||||
|
||||
updateBoundsWithPolylines: ()->
|
||||
|
||||
updateBoundsWithPolygons: ()->
|
||||
|
||||
updateBoundsWithCircles: ()->
|
||||
|
||||
extendMapBounds :->
|
||||
|
||||
adaptMapToBounds: ->
|
||||
@fitBounds()
|
||||
@@ -1,261 +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
|
||||
@polylinesLayer = 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)
|
||||
@serviceObject.addLayer(@markersLayer)
|
||||
#//TODO move?
|
||||
@markersLayer.events.register("featureselected", @markersLayer, @onFeatureSelect)
|
||||
@markersLayer.events.register("featureunselected", @markersLayer, @onFeatureUnselect)
|
||||
@markersControl = new OpenLayers.Control.SelectFeature(@markersLayer)
|
||||
@serviceObject.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.marker_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: ->
|
||||
@serviceObject.removeLayer(@markersLayer) if @markersLayer != null and @serviceObject.getLayer(@markersLayer.id) != null
|
||||
|
||||
extendBoundsWithMarkers: ->
|
||||
console.log "here"
|
||||
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()
|
||||
@serviceObject.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: ->
|
||||
@serviceObject.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
|
||||
|
||||
#////////////////////////////////////////////////////
|
||||
#/////////////////// POLYLINES //////////////////////
|
||||
#////////////////////////////////////////////////////
|
||||
|
||||
create_polyline : (polyline) ->
|
||||
|
||||
if(@polylinesLayer == null)
|
||||
@polylinesLayer = new OpenLayers.Layer.Vector("Polylines", null)
|
||||
@serviceObject.addLayer(@polylinesLayer)
|
||||
@polylinesLayer.events.register("featureselected", @polylinesLayer, @onFeatureSelect)
|
||||
@polylinesLayer.events.register("featureunselected", @polylinesLayer, @onFeatureUnselect)
|
||||
@polylinesControl = new OpenLayers.Control.DrawFeature(@polylinesLayer, OpenLayers.Handler.Path)
|
||||
@serviceObject.addControl(@polylinesControl)
|
||||
|
||||
polyline_coordinates = []
|
||||
|
||||
for element in polyline
|
||||
#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 = new OpenLayers.Geometry.Point(element.lng, element.lat)
|
||||
polyline_coordinates.push(latlng)
|
||||
|
||||
line_points = new OpenLayers.Geometry.LineString(polyline_coordinates);
|
||||
line_style = { strokeColor: strokeColor, strokeOpacity: strokeOpacity, strokeWidth: strokeWeight };
|
||||
|
||||
polyline = new OpenLayers.Feature.Vector(line_points, null, line_style);
|
||||
polyline.geometry.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"))
|
||||
|
||||
@polylinesLayer.addFeatures([polyline])
|
||||
|
||||
return polyline
|
||||
|
||||
updateBoundsWithPolylines: ()->
|
||||
|
||||
updateBoundsWithPolygons: ()->
|
||||
|
||||
updateBoundsWithCircles: ()->
|
||||
|
||||
# #////////////////////////////////////////////////////
|
||||
# #/////////////////// Other methods //////////////////
|
||||
# #////////////////////////////////////////////////////
|
||||
|
||||
fitBounds: ->
|
||||
@serviceObject.zoomToExtent(@boundsObject, true)
|
||||
|
||||
centerMapOnUser: ->
|
||||
@serviceObject.setCenter @userLocation
|
||||
|
||||
extendMapBounds :->
|
||||
|
||||
adaptMapToBounds: ->
|
||||
@fitBounds()
|
||||
@@ -1,4 +0,0 @@
|
||||
/*! Backstretch - v2.0.4 - 2013-06-19
|
||||
* http://srobbin.com/jquery-plugins/backstretch/
|
||||
* Copyright (c) 2013 Scott Robbin; Licensed MIT */
|
||||
(function(a,d,p){a.fn.backstretch=function(c,b){(c===p||0===c.length)&&a.error("No images were supplied for Backstretch");0===a(d).scrollTop()&&d.scrollTo(0,0);return this.each(function(){var d=a(this),g=d.data("backstretch");if(g){if("string"==typeof c&&"function"==typeof g[c]){g[c](b);return}b=a.extend(g.options,b);g.destroy(!0)}g=new q(this,c,b);d.data("backstretch",g)})};a.backstretch=function(c,b){return a("body").backstretch(c,b).data("backstretch")};a.expr[":"].backstretch=function(c){return a(c).data("backstretch")!==p};a.fn.backstretch.defaults={centeredX:!0,centeredY:!0,duration:5E3,fade:0};var r={left:0,top:0,overflow:"hidden",margin:0,padding:0,height:"100%",width:"100%",zIndex:-999999},s={position:"absolute",display:"none",margin:0,padding:0,border:"none",width:"auto",height:"auto",maxHeight:"none",maxWidth:"none",zIndex:-999999},q=function(c,b,e){this.options=a.extend({},a.fn.backstretch.defaults,e||{});this.images=a.isArray(b)?b:[b];a.each(this.images,function(){a("<img />")[0].src=this});this.isBody=c===document.body;this.$container=a(c);this.$root=this.isBody?l?a(d):a(document):this.$container;c=this.$container.children(".backstretch").first();this.$wrap=c.length?c:a('<div class="backstretch"></div>').css(r).appendTo(this.$container);this.isBody||(c=this.$container.css("position"),b=this.$container.css("zIndex"),this.$container.css({position:"static"===c?"relative":c,zIndex:"auto"===b?0:b,background:"none"}),this.$wrap.css({zIndex:-999998}));this.$wrap.css({position:this.isBody&&l?"fixed":"absolute"});this.index=0;this.show(this.index);a(d).on("resize.backstretch",a.proxy(this.resize,this)).on("orientationchange.backstretch",a.proxy(function(){this.isBody&&0===d.pageYOffset&&(d.scrollTo(0,1),this.resize())},this))};q.prototype={resize:function(){try{var a={left:0,top:0},b=this.isBody?this.$root.width():this.$root.innerWidth(),e=b,g=this.isBody?d.innerHeight?d.innerHeight:this.$root.height():this.$root.innerHeight(),j=e/this.$img.data("ratio"),f;j>=g?(f=(j-g)/2,this.options.centeredY&&(a.top="-"+f+"px")):(j=g,e=j*this.$img.data("ratio"),f=(e-b)/2,this.options.centeredX&&(a.left="-"+f+"px"));this.$wrap.css({width:b,height:g}).find("img:not(.deleteable)").css({width:e,height:j}).css(a)}catch(h){}return this},show:function(c){if(!(Math.abs(c)>this.images.length-1)){var b=this,e=b.$wrap.find("img").addClass("deleteable"),d={relatedTarget:b.$container[0]};b.$container.trigger(a.Event("backstretch.before",d),[b,c]);this.index=c;clearInterval(b.interval);b.$img=a("<img />").css(s).bind("load",function(f){var h=this.width||a(f.target).width();f=this.height||a(f.target).height();a(this).data("ratio",h/f);a(this).fadeIn(b.options.speed||b.options.fade,function(){e.remove();b.paused||b.cycle();a(["after","show"]).each(function(){b.$container.trigger(a.Event("backstretch."+this,d),[b,c])})});b.resize()}).appendTo(b.$wrap);b.$img.attr("src",b.images[c]);return b}},next:function(){return this.show(this.index<this.images.length-1?this.index+1:0)},prev:function(){return this.show(0===this.index?this.images.length-1:this.index-1)},pause:function(){this.paused=!0;return this},resume:function(){this.paused=!1;this.next();return this},cycle:function(){1<this.images.length&&(clearInterval(this.interval),this.interval=setInterval(a.proxy(function(){this.paused||this.next()},this),this.options.duration));return this},destroy:function(c){a(d).off("resize.backstretch orientationchange.backstretch");clearInterval(this.interval);c||this.$wrap.remove();this.$container.removeData("backstretch")}};var l,f=navigator.userAgent,m=navigator.platform,e=f.match(/AppleWebKit\/([0-9]+)/),e=!!e&&e[1],h=f.match(/Fennec\/([0-9]+)/),h=!!h&&h[1],n=f.match(/Opera Mobi\/([0-9]+)/),t=!!n&&n[1],k=f.match(/MSIE ([0-9]+)/),k=!!k&&k[1];l=!((-1<m.indexOf("iPhone")||-1<m.indexOf("iPad")||-1<m.indexOf("iPod"))&&e&&534>e||d.operamini&&"[object OperaMini]"==={}.toString.call(d.operamini)||n&&7458>t||-1<f.indexOf("Android")&&e&&533>e||h&&6>h||"palmGetResource"in d&&e&&534>e||-1<f.indexOf("MeeGo")&&-1<f.indexOf("NokiaBrowser/8.5.0")||k&&6>=k)})(jQuery,window);
|
||||
@@ -1,62 +0,0 @@
|
||||
//;(function (window, document, $) {
|
||||
// alert($("#sidebarButton").html());
|
||||
//}(this, document, jQuery));
|
||||
|
||||
|
||||
|
||||
|
||||
//;(function (window, document, $) {
|
||||
// // Set the negative margin on the top menu for slide-menu pages
|
||||
// var $selector1 = $('#topMenu'),
|
||||
// events = 'click.fndtn';
|
||||
// if ($selector1.length > 0) $selector1.css("margin-top", $selector1.height() * -1);
|
||||
//
|
||||
// // Watch for clicks to show the sidebar
|
||||
// var $selector2 = $('#sidebarButton');
|
||||
// if ($selector2.length > 0) {
|
||||
// $('#sidebarButton').on(events, function (e) {
|
||||
// console.log("testing one two three");
|
||||
// e.preventDefault();
|
||||
// $('body').toggleClass('active');
|
||||
// });
|
||||
// }
|
||||
// else {
|
||||
// console.log("not supposed to be there");
|
||||
// }
|
||||
//
|
||||
// // Watch for clicks to show the menu for slide-menu pages
|
||||
// var $selector3 = $('#menuButton');
|
||||
// if ($selector3.length > 0) {
|
||||
// $('#menuButton').on(events, function (e) {
|
||||
// e.preventDefault();
|
||||
// $('body').toggleClass('active-menu');
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// // // Adjust sidebars and sizes when resized
|
||||
// // $(window).resize(function() {
|
||||
// // // if (!navigator.userAgent.match(/Android/i)) $('body').removeClass('active');
|
||||
// // var $selector4 = $('#topMenu');
|
||||
// // if ($selector4.length > 0) $selector4.css("margin-top", $selector4.height() * -1);
|
||||
// // });
|
||||
//
|
||||
// // Switch panels for the paneled nav on mobile
|
||||
// var $selector5 = $('#switchPanels');
|
||||
// if ($selector5.length > 0) {
|
||||
// $('#switchPanels dd').on(events, function (e) {
|
||||
// e.preventDefault();
|
||||
// var switchToPanel = $(this).children('a').attr('href'),
|
||||
// switchToIndex = $(switchToPanel).index();
|
||||
// $(this).toggleClass('active').siblings().removeClass('active');
|
||||
// $(switchToPanel).parent().css("left", (switchToIndex * (-100) + '%'));
|
||||
// });
|
||||
// }
|
||||
//
|
||||
// $('#nav li a').on(events, function (e) {
|
||||
// alert("test");
|
||||
// e.preventDefault();
|
||||
// var href = $(this).attr('href'),
|
||||
// $target = $(href);
|
||||
// $('html, body').animate({scrollTop : $target.offset().top}, 300);
|
||||
// });
|
||||
//}(this, document, jQuery));
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +0,0 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
|
||||
@@ -9,7 +9,5 @@
|
||||
//= require store/spree_core
|
||||
//= require store/spree_auth
|
||||
//= require store/spree_promo
|
||||
//= require angular
|
||||
//= require angular-resource
|
||||
|
||||
//= require_tree .
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
$(document).ready ->
|
||||
$('#cart_adjustments').hide()
|
||||
|
||||
$('th.cart-adjustment-header').html('<a href="#">Distribution...</a>')
|
||||
$('th.cart-adjustment-header a').click ->
|
||||
$('#cart_adjustments').toggle()
|
||||
$('th.cart-adjustment-header a').html('Distribution')
|
||||
false
|
||||
@@ -1,20 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
angular.module('store', ['ngResource']).
|
||||
controller('CartCtrl', ['$scope', '$window', 'CartFactory', ($scope, $window, CartFactory) ->
|
||||
|
||||
$scope.state = 'Empty'
|
||||
|
||||
$scope.loadCart = (cart_id) ->
|
||||
if cart_id?
|
||||
CartFactory.load cart_id, (cart) ->
|
||||
$scope.cart = cart
|
||||
if $scope.cart?.orders?.length > 0
|
||||
$scope.state = "There's something there...."
|
||||
|
||||
$scope.addVariant = (variant, quantity) ->
|
||||
|
||||
])
|
||||
.config(['$httpProvider', ($httpProvider) ->
|
||||
$httpProvider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content')
|
||||
])
|
||||
@@ -1,11 +0,0 @@
|
||||
'use strict'
|
||||
|
||||
angular.module('store').
|
||||
factory('CartFactory', ['$resource', '$window', '$http', ($resource, $window, $http) ->
|
||||
Cart = $resource '/open_food_network/cart/:cart_id.json', {},
|
||||
{ 'show': { method: 'GET'} }
|
||||
|
||||
load: (id, callback) ->
|
||||
Cart.show {cart_id: id}, (cart) ->
|
||||
callback(cart)
|
||||
])
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* Update the price on the product details page in real time when the variant or the quantity are changed.
|
||||
**/
|
||||
|
||||
$(document).ready(function() {
|
||||
// Product page with variant choice
|
||||
$("#product-variants input[type='radio']").change(products_update_price_with_variant);
|
||||
$("#quantity").change(products_update_price_with_variant);
|
||||
$("#quantity").change();
|
||||
|
||||
// Product page with master price only
|
||||
$(".add-to-cart input.title:not(#quantity):not(.max_quantity)").change(products_update_price_without_variant).change();
|
||||
|
||||
// Product page other
|
||||
$("#distributor_id").change(function() {
|
||||
var distributor_html = distributors[$(this).val()];
|
||||
if(!distributor_html) {
|
||||
distributor_html = 'When you select a distributor for your order, their address and pickup times will be displayed here.';
|
||||
}
|
||||
$("#product-distributor-details .distributor-details").html(distributor_html);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function products_update_price_with_variant() {
|
||||
var variant_price = $("#product-variants input[type='radio']:checked").parent().find("span.price").html().trim();
|
||||
variant_price = variant_price.substr(2, variant_price.length-3);
|
||||
|
||||
var quantity = $("#quantity").val();
|
||||
|
||||
$("#product-price span.price").html("$"+(parseFloat(variant_price) * parseInt(quantity)).toFixed(2));
|
||||
}
|
||||
|
||||
|
||||
function products_update_price_without_variant() {
|
||||
var master_price = $("#product-price span.price").data('master-price');
|
||||
if(master_price == null) {
|
||||
// Store off the master price
|
||||
master_price = $("#product-price span.price").html();
|
||||
master_price = master_price.substring(1);
|
||||
$("#product-price span.price").data('master-price', master_price);
|
||||
}
|
||||
|
||||
var quantity = $(this).val();
|
||||
|
||||
$("#product-price span.price").html("$"+(parseFloat(master_price)*parseInt(quantity)).toFixed(2));
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
$(document).ready ->
|
||||
$("#order_order_cycle_id").change -> $("#order_cycle_select").submit()
|
||||
$("#reset_order_cycle").click -> return false unless confirm "Changing your collection date will clear your cart."
|
||||
$(".shop-distributor.empties-cart").click -> return false unless confirm "Changing your location will clear your cart."
|
||||
@@ -1,4 +0,0 @@
|
||||
%ng-include{src: "'partials/enterprise_header.html'"}
|
||||
%ng-include{src: "'partials/enterprise_details.html'"}
|
||||
%ng-include{src: "'partials/hub_actions.html'"}
|
||||
%ng-include{src: "'partials/close.html'"}
|
||||
@@ -1,13 +1,13 @@
|
||||
.highlight{"ng-class" => "{'has_shopfront' : enterprise.has_shopfront}"}
|
||||
.highlight{"ng-class" => "{'is_distributor' : enterprise.is_distributor}"}
|
||||
.highlight-top.row
|
||||
.small-12.medium-7.large-8.columns
|
||||
%h3{"ng-if" => "enterprise.has_shopfront"}
|
||||
%h3{"ng-if" => "enterprise.is_distributor"}
|
||||
%a{"bo-href" => "enterprise.path", "ofn-empties-cart" => "enterprise", bindonce: true}
|
||||
%i{"ng-class" => "enterprise.icon_font"}
|
||||
%span {{ enterprise.name }}
|
||||
%h3{"ng-if" => "!enterprise.has_shopfront", "ng-class" => "{'is_producer' : enterprise.is_primary_producer}"}
|
||||
%h3{"ng-if" => "!enterprise.is_distributor", "ng-class" => "{'is_producer' : enterprise.is_primary_producer}"}
|
||||
%i{"ng-class" => "enterprise.icon_font"}
|
||||
%span {{ enterprise.name }}
|
||||
.small-12.medium-5.large-4.columns.text-right.small-only-text-left
|
||||
%p {{ [enterprise.address.city, enterprise.address.state_name] | printArray}}
|
||||
%img.hero-img{"ng-src" => "{{enterprise.promo_image}}"}
|
||||
%img.hero-img{"ng-src" => "{{enterprise.promo_image}}"}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.row.pad-top{bindonce: true, "ng-if" => "enterprise.hubs.length > 0 && enterprise.has_shopfront"}
|
||||
.row.pad-top{bindonce: true, "ng-if" => "enterprise.hubs.length > 0 && enterprise.is_distributor"}
|
||||
.cta-container.small-12.columns
|
||||
%label
|
||||
Shop for
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.row.pad-top{bindonce: true, ng: { if: 'enterprise.has_shopfront' } }
|
||||
.row.pad-top{bindonce: true, ng: { if: 'enterprise.is_distributor' } }
|
||||
.cta-container.small-12.columns
|
||||
.row
|
||||
.small-4.columns
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
%ng-include{src: "'partials/enterprise_header.html'"}
|
||||
%ng-include{src: "'partials/enterprise_details.html'"}
|
||||
%ng-include{src: "'partials/close.html'"}
|
||||
@@ -1,26 +1,27 @@
|
||||
.container#registration-details{bindonce: true}
|
||||
.header
|
||||
%h2 Let's Get Started
|
||||
%h5{ bo: { if: "enterprise.type != 'single'" } } Woot! First we need to know what sort of enterprise you are:
|
||||
%h5{ bo: { if: "enterprise.type == 'single'" } } Woot! First we need to know the name of your farm:
|
||||
%h5{ bo: { if: "enterprise.sells != 'own'" } } Woot! First we need to know what sort of enterprise you are:
|
||||
%h5{ bo: { if: "enterprise.sells == 'own'" } } Woot! First we need to know the name of your farm:
|
||||
%ng-include{ src: "'registration/steps.html'" }
|
||||
%form{ name: 'details', novalidate: true, ng: { controller: "RegistrationFormCtrl", submit: "selectIfValid('address',details)" } }
|
||||
.row
|
||||
.small-12.columns.field
|
||||
%label{ for: 'enterprise_name', bo: { if: "enterprise.type != 'single'" } } Enterprise Name:
|
||||
%label{ for: 'enterprise_name', bo: { if: "enterprise.type == 'single'" } } Farm Name:
|
||||
%label{ for: 'enterprise_name', bo: { if: "enterprise.sells != 'own'" } } Enterprise Name:
|
||||
%label{ for: 'enterprise_name', bo: { if: "enterprise.sells == 'own'" } } Farm Name:
|
||||
%input.chunky.small-12.columns{ id: 'enterprise_name', name: 'name', placeholder: "eg. Charlie's Awesome Farm", required: true, ng: { model: 'enterprise.name' } }
|
||||
%span.error.small-12.columns{ ng: { show: "details.name.$error.required && submitted" } }
|
||||
You need to enter a name for your enterprise!
|
||||
|
||||
.row#enterprise-types{ 'data-equalizer' => true, bo: { if: "enterprise.type != 'single'" } }
|
||||
.row#enterprise-types{ 'data-equalizer' => true, bo: { if: "enterprise.sells != 'own'" } }
|
||||
.small-12.columns.field
|
||||
.row
|
||||
.small-12.columns
|
||||
%label Choose one:
|
||||
.row
|
||||
-# TODO redesign this to refelct the extra options available.
|
||||
.small-12.medium-4.large-4.columns{ 'data-equalizer-watch' => true }
|
||||
%a.panel#producer-panel{ href: "#", ng: { click: "enterprise.is_distributor = false; enterprise.is_primary_producer = true", class: "{selected: (!enterprise.is_distributor && enterprise.is_primary_producer)}" } }
|
||||
%a.panel#producer-panel{ href: "#", ng: { click: "enterprise.is_primary_producer = true", class: "{selected: (!enterprise.is_distributor && enterprise.is_primary_producer)}" } }
|
||||
.left
|
||||
/ %render-svg{ path: "/assets/map-icon-producer.svg" }
|
||||
%h4 I'm A Producer
|
||||
|
||||
Reference in New Issue
Block a user