Created
December 2, 2016 00:00
-
-
Save Jks15063/38d7160c929e99498ebab3bcdfc036ad to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
finiteBounds = (bounds) -> | |
ne = bounds.northeast | |
sw = bounds.southwest | |
return (isFinite(ne.lat) && isFinite(ne.lng) && isFinite(sw.lat) && isFinite(sw.lng)) | |
getBoundsZoomLevel = (bounds, size) -> | |
latRad = (lat) -> | |
sin = Math.sin(lat * Math.PI / 180) | |
radX2 = Math.log((1 + sin) / (1 - sin)) / 2 | |
Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2 | |
zoom = (mapPx, worldPx, fraction) -> | |
Math.floor Math.log((mapPx / worldPx) / fraction) / Math.LN2 | |
WORLD_DIM = | |
height: 256 | |
width: 256 | |
ZOOM_MAX = 21 | |
ne = bounds.northeast | |
sw = bounds.southwest | |
return 8 if not finiteBounds(bounds) | |
latFraction = (latRad(ne.lat) - latRad(sw.lat)) / Math.PI | |
lngDiff = ne.lng - sw.lng | |
lngFraction = ((if (lngDiff < 0) then (lngDiff + 360) else lngDiff)) / 360 | |
latZoom = zoom(size.y, WORLD_DIM.height, latFraction) | |
lngZoom = zoom(size.x, WORLD_DIM.width, lngFraction) | |
Math.min latZoom, lngZoom, ZOOM_MAX | |
maps = angular.module('wm-maps') | |
maps.directive 'wmListingsMap', ($rootScope, wmMarkerService, $timeout, wmHelpers) -> | |
class Controller | |
constructor: ($scope, $modal, $window, leafletData) -> | |
$scope.mapControl = leafletData | |
$scope.limitZoomReload = true | |
$scope.$on 'leafletDirectiveMap.dragend', (event, args) -> | |
amountMoved = args?.leafletEvent?.distance | |
mapHeight = args?.leafletEvent?.target?._size?.y | |
if !amountMoved || !mapHeight || amountMoved > mapHeight * 0.35 | |
$scope.userMovedMap() | |
$scope.$on 'leafletDirectiveMap.zoomend', (event, args) -> | |
if $scope.mapLoaded | |
newZoom = args?.leafletEvent?.target?._zoom | |
# Don't reload pins if user is zooming in after initial load. | |
if !$scope.limitZoomReload || !newZoom || newZoom < $scope.zoom | |
# After user has zoomed out, reload pins every zoom. | |
$scope.limitZoomReload = false | |
$scope.userMovedMap() | |
else | |
$scope.userMovedMap() | |
$scope.$on 'wmListingDetail.clicked', (_event, listing) -> | |
listing.marker._cachedEventName = _event.name | |
listing.marker?.openPopup() | |
if $scope.bounds && finiteBounds($scope.bounds) | |
bounds = new L.latLngBounds( | |
new L.latLng($scope.bounds.southwest.lat, $scope.bounds.southwest.lng), | |
new L.latLng($scope.bounds.northeast.lat, $scope.bounds.northeast.lng), | |
) | |
center = bounds.getCenter() | |
$scope.center = | |
lat: center.lat | |
lng: center.lng | |
zoom: window.defaultMapZoom | |
else if $rootScope?.regionData?.location? | |
location = $rootScope.regionData.location | |
$scope.center = | |
lat: location.latitude | |
lng: location.longitude | |
zoom: window.defaultMapZoom | |
$scope.widenSearch = -> | |
$scope.mapControl.getMap().then (map) => | |
size = map.getSize() | |
$scope.zoom = getBoundsZoomLevel($scope.bounds, size) - 1 | |
map.setZoom($scope.zoom - 1) | |
$scope.updateBounds | |
if $scope.modal? | |
$('.modal').css('display', 'none') | |
if $rootScope.siteScope == 'dispensary' | |
$scope.listingType = 'storefronts' | |
$scope.lookForType = 'deliveries' | |
$scope.lookForOther = -> | |
$window.location.href = '/deliveries?from-region=' + $rootScope.regionData.name | |
this.$hide() | |
else | |
$scope.listingType = 'deliveries' | |
$scope.lookForType = 'storefronts' | |
$scope.lookForOther = -> | |
$window.location.href = '/dispensaries?from-region=' + $rootScope.regionData.name | |
show = -> | |
($rootScope.regionData?.name != undefined) && | |
$scope.listings.length == 0 && | |
!$rootScope.isCardsMap && | |
($rootScope.siteScope == 'dispensary' || $rootScope.siteScope == 'delivery') | |
$scope.noListings = -> | |
if $scope.modal? | |
$('.modal').css('display', 'block') | |
else | |
console.log('CREATE') | |
$scope.modal = $modal( | |
template:'modal/noListings.html', | |
show: show(), | |
scope: $scope | |
) | |
# console.log('HEAD') | |
# $scope.noListings() | |
onEachFeature = (feature, layer) -> | |
editLink = '/new_admin/regions/' + feature.properties.slug + '/edit' | |
popupContent = '<div id="wm_map_infobox_content">' + | |
'<div class="region_name hovers">' + | |
"<a target=\"_blank\" href=\"#{editLink}\">" + feature.properties.name + '</a>' + | |
'</div>' + | |
'</div>' | |
layer.bindPopup popupContent | |
return | |
geoData = [] | |
addRegionGeoJson = (_region) -> | |
if _region?.geometry | |
geojson = JSON.parse(_region.geometry) | |
geojson.properties = | |
name: _region.name | |
slug: _region.slug | |
geoData.push(geojson) | |
addRegionGeoJson($rootScope.regionData) | |
if $scope.subregions | |
$scope.subregions.forEach (_region) -> | |
addRegionGeoJson(_region) | |
angular.extend $scope, | |
mapOptions: | |
scrollWheelZoom: true | |
attributionControl: false | |
tileLayer: window.tileServerUrl | |
zoomControlPosition: 'topright' | |
tileLayerOptions: window.tileLayerDefaults | |
center: $scope.center | |
markers: [] | |
controls: | |
custom: new L.control.attribution(prefix: false) | |
geojson: | |
data: | |
"type": "FeatureCollection" | |
"features": geoData | |
style: | |
fillColor: 'teal' | |
weight: 1 | |
opacity: 1 | |
color: 'white' | |
dashArray: '3' | |
fillOpacity: 0.4 | |
onEachFeature: onEachFeature | |
link = ($scope, $el, $attrs, listingsController) -> | |
$scope.updateBounds = listingsController.updateBounds | |
if $rootScope.wmRollout?.new_header | |
$el.addClass('with-new-header') | |
$scope.centerChanged = -> | |
listingsController.centerChanged() | |
$scope.userMovedMap = => | |
$timeout.cancel @userMovedMapDebounce | |
@userMovedMapDebounce = $timeout (=> | |
# We don't want to call centerChanged() until after the map has | |
# loaded and had all its initial values set. This happens after | |
# $scope.zoom is set. | |
if $scope.mapLoaded | |
$rootScope.lockedToRegion = false | |
$scope.updateBounds() | |
$scope.centerChanged() | |
$scope.mapLoaded = !!$scope.zoom | |
), 200 | |
resetMarkers = (map) -> | |
for marker in $scope.markers | |
map.removeLayer(marker) | |
$scope.markers = [] | |
addListings = (map, listings) -> | |
if listings && listings.length > 0 | |
for listing, index in listings | |
marker = wmMarkerService.setupMarker(listing, map, $scope) | |
$scope.markers.push(marker) | |
fitMapToListingCards = (map, listings) -> | |
if listings && listings.length > 0 | |
# Create L.latLng objs for all listings and fit the map to show them. | |
ltlngs = [] | |
listings.forEach (listing) => | |
ltlngs.push(new L.latLng(listing.latitude, listing.longitude)) | |
map.fitBounds(L.latLngBounds(ltlngs)) | |
# If we are zoomed in too much then set the map zoom to our default. | |
if map.getZoom() > window.defaultMapZoom # FIXME: Is this what we want for the min? | |
map.setZoom(window.defaultMapZoom) | |
# Set the starting zoom to the zoom for cards. | |
$scope.zoom = map.getZoom() | |
# We finished showing the cards. From now on we are showing regular listings. | |
$rootScope.isCardsMap = false | |
# Make sure the map is considered loaded. | |
$scope.mapLoaded = true | |
# Load more pins to fill map. | |
$scope.userMovedMap() | |
# NOTE: here | |
$scope.$watch 'listings', (listings) -> | |
$scope.mapControl.getMap().then (map) -> | |
if listings.length is 0 | |
$scope.noListings() | |
else | |
if $scope.modal? | |
$('.modal').css('display', 'none') | |
resetMarkers(map) | |
addListings(map, listings) | |
# If we are showing markers for Cards. Fit to cards and fill map with other markers. | |
fitMapToListingCards(map, listings) if $rootScope.isCardsMap | |
$scope.$watch 'bounds', (bounds) -> | |
$scope.updateBounds() | |
$scope.mapControl.getMap().then (map) -> | |
size = map.getSize() | |
if !bounds || size.x == 0 | |
$scope.zoom = map.getZoom() | |
$scope.mapLoaded = true | |
return | |
$scope.zoom = getBoundsZoomLevel($scope.bounds, size) | |
current_zoom = map.getZoom() | |
if $scope.zoom == current_zoom | |
$scope.mapLoaded = true | |
else | |
map.setZoom($scope.zoom) | |
$scope.$on '$destroy', => | |
$timeout.cancel @updateListingsDebounce | |
params = wmHelpers.userLocationParams | |
'listing type': $scope.lookForType | |
'page url': window.location.href | |
if window.location.pathname.match(/\/nearby|in\//i) | |
wmHelpers.logAnalyticsEvent 'region - viewed map page', params | |
restrict: 'E' | |
templateUrl: 'wm_maps/listings_map.html' | |
require: '^wmListings' | |
controller: ['$scope', '$modal', '$window', 'leafletData', Controller] | |
link: link | |
scope: true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment