lib/ProMotion/map/map_screen_module.rb in ProMotion-mapbox-0.1.3 vs lib/ProMotion/map/map_screen_module.rb in ProMotion-mapbox-0.2.0

- old
+ new

@@ -4,51 +4,35 @@ PIN_COLORS = { red: UIColor.redColor, green: UIColor.greenColor, purple: UIColor.purpleColor } - + def screen_setup - mapbox_setup self.view = nil - self.view = RMMapView.alloc.initWithFrame(self.view.bounds, andTilesource:@tileSource) + self.view = MGLMapView.alloc.initWithFrame(self.view.bounds, styleURL: self.class.get_map_style) self.view.delegate = self + check_annotation_data @promotion_annotation_data = [] + set_up_start_position set_up_tap_to_add end - - def mapbox_setup - if self.class.respond_to?(:get_mapbox_setup) && self.class.get_mapbox_setup - setup_params = self.class.get_mapbox_setup_params - else - PM.logger.error "Missing Mapbox setup data." - end - RMConfiguration.sharedInstance.setAccessToken(setup_params[:access_token]) if RMConfiguration.sharedInstance.accessToken.nil? - @tileSource = RMMapboxSource.alloc.initWithMapID(setup_params[:tile_source]) - end - - def view_will_appear(animated) - super + + def on_appear update_annotation_data - set_up_start_center end - def view_did_appear(animated) - super - set_up_start_region - end - def check_annotation_data PM.logger.error "Missing #annotation_data method in MapScreen #{self.class.to_s}." unless self.respond_to?(:annotation_data) end def update_annotation_data clear_annotations add_annotations annotation_data end - + def map self.view end alias_method :mapview, :map @@ -78,12 +62,13 @@ def hide_user_location set_show_user_location false end - def set_show_user_location(show) + def set_show_user_location(show,mode=MGLUserTrackingModeFollow) self.view.showsUserLocation = show + self.view.userTrackingMode = mode end def showing_user_location? self.view.showsUserLocation end @@ -91,11 +76,11 @@ def user_location user_annotation.nil? ? nil : user_annotation.coordinate end def user_annotation - self.view.userLocation.nil? ? nil : self.view.userLocation.location + self.view.userLocation.location.nil? ? nil : self.view.userLocation.location end def zoom_to_user(radius = 0.05, animated=true) show_user_location unless showing_user_location? set_region(create_region(user_location,radius), animated) @@ -111,99 +96,59 @@ def select_annotation_at(annotation_index, animated=true) select_annotation(annotations[annotation_index], animated:animated) end - def selected_annotation - self.view.selectedAnnotation + def selected_annotations + self.view.selectedAnnotations end - def deselect_annotation(animated=false) - unless selected_annotation.nil? - self.view.deselectAnnotation(selected_annotation, animated:animated) + def deselect_annotations(animated=false) + unless selected_annotations.nil? + selected_annotations.each do |annotation| + self.view.deselectAnnotation(annotation, animated:animated) + end end end def add_annotation(annotation) - @promotion_annotation_data << MapScreenAnnotation.new(annotation,self.view) + @promotion_annotation_data << MapScreenAnnotation.new(annotation) self.view.addAnnotation @promotion_annotation_data.last end def add_annotations(annotations) - @promotion_annotation_data = Array(annotations).map{|a| MapScreenAnnotation.new(a,self.view)} + @promotion_annotation_data = Array(annotations).map{|a| MapScreenAnnotation.new(a)} self.view.addAnnotations @promotion_annotation_data end + def clear_annotation(annotation) + self.view.removeAnnotation(annotation) + @promotion_annotation_data.delete(annotation) + end + def clear_annotations - @promotion_annotation_data.each do |a| - self.view.removeAnnotation(a) - end + self.view.removeAnnotations(@promotion_annotation_data) @promotion_annotation_data = [] end - def annotation_view(map_view, annotation) - return if annotation.is_a? RMUserLocation - - params = annotation.params - - identifier = params[:identifier] - # Set the pin properties - if params[:image] - view = RMMarker.alloc.initWithUIImage(params[:image]) - else - pinColor = (PIN_COLORS[params[:pin_color]] || params[:pin_color]) - view = RMMarker.alloc.initWithMapboxMarkerImage(params[:maki_icon], tintColor: pinColor) - end - view.annotation = annotation - view.canShowCallout = params[:show_callout] if view.respond_to?("canShowCallout=") - - if params[:left_accessory] - view.leftCalloutAccessoryView = params[:left_accessory] - end - if params[:right_accessory] - view.rightCalloutAccessoryView = params[:right_accessory] - end - - if params[:action] - button_type = params[:action_button_type] || UIButtonTypeDetailDisclosure - - action_button = UIButton.buttonWithType(button_type) - action_button.addTarget(self, action: params[:action], forControlEvents:UIControlEventTouchUpInside) - - view.rightCalloutAccessoryView = action_button - end - view - end - def set_start_position(params={}) params = { latitude: 37.331789, longitude: -122.029620, radius: 10 }.merge(params) + initialLocation = CLLocationCoordinate2D.new(params[:latitude], params[:longitude]) region = create_region(initialLocation,params[:radius]) set_region(region, animated:false) end - def set_up_start_region + def set_up_start_position if self.class.respond_to?(:get_start_position) && self.class.get_start_position - start_params = self.class.get_start_position_params - self.set_start_position start_params unless start_params[:radius].nil? + self.set_start_position self.class.get_start_position_params end end - - def set_up_start_center - if self.class.respond_to?(:get_start_position) && self.class.get_start_position - start_params = self.class.get_start_position_params - start_params[:zoom] ||= 5 - self.view.setZoom(start_params[:zoom], atCoordinate: - CLLocationCoordinate2D.new(start_params[:latitude], start_params[:longitude]), - animated: false - ) - end - end def set_tap_to_add(params={}) params = { length: 2.0, target: self, @@ -279,17 +224,17 @@ set_region(fits, animated: args[:animated]) end def set_region(region, animated=true) - self.view.zoomWithLatitudeLongitudeBoundsSouthWest( - region[:southWest], - northEast: region[:northEast], + self.view.setVisibleCoordinateBounds( + [region[:southWest], region[:northEast]], animated: animated ) end - + + ###### REGION SETTINGS ####### def deg_to_rad(angle) angle*Math::PI/180 end def rad_to_deg(angle) @@ -306,30 +251,40 @@ output_latitude = Math.asin( Math.sin(input_latitude) * Math.cos(distance) + Math.cos(input_latitude) * Math.sin(distance) * Math.cos(bearing) ) - + dlon = input_longitude + Math.atan2( Math.sin(bearing) * Math.sin(distance) * Math.cos(input_longitude), Math.cos(distance) - Math.sin(input_longitude) * Math.sin(output_latitude) ) - + output_longitude = (dlon + 3*Math::PI) % (2*Math::PI) - Math::PI CLLocationCoordinate2DMake(rad_to_deg(output_latitude), rad_to_deg(output_longitude)) end - + def create_region(initialLocation,radius=10) return nil unless initialLocation.is_a? CLLocationCoordinate2D radius = radius * 1.820 # Meters equivalent to 1 Nautical Mile southWest = self.point_from_location_bearing_and_distance(initialLocation,225, radius) northEast = self.point_from_location_bearing_and_distance(initialLocation,45, radius) {:southWest => southWest, :northEast => northEast} end alias_method :region, :create_region - + + ##### END REGION SETTINGS ###### + ##### MAP STYLE SETTINGS ###### + def set_map_style + if self.class.respond_to?(:get_map_style) + self.view.styleURL = self.class.get_map_style + end + end + ##### END MAP STYLE SETTINGS ###### + + def look_up_address(args={}, &callback) args[:address] = args if args.is_a? String # Assume if a string is passed that they want an address geocoder = CLGeocoder.new return geocoder.geocodeAddressDictionary(args[:address], completionHandler: callback) if args[:address].is_a?(Hash) @@ -347,22 +302,58 @@ PM.logger.info("You're trying to reverse geocode something that isn't a CLLocation") callback.call nil, nil end end - def empty_cache - map.removeAllCachedImages + ########## Mapbox GL methods ################# + def mapView(mapView, annotationCanShowCallout: annotation) + return nil if annotation.is_a? MGLUserLocation + annotation.params[:show_callout] end - ########## Mapbox methods ################# - def mapView(map_view, layerForAnnotation: annotation) - if annotation.is_a?(RMAnnotation) - annotation = MapScreenAnnotation.new_with_rmannotation(annotation,self.view) + def mapView(mapView, imageForAnnotation: annotation) + return nil unless annotation.params[:image] + annotationImage = mapView.dequeueReusableAnnotationImageWithIdentifier(annotation.params[:image]) + if !annotationImage + image = UIImage.imageNamed(annotation.params[:image]) + annotationImage = MGLAnnotationImage.annotationImageWithImage(image, reuseIdentifier: annotation.params[:image]) + return annotationImage end - annotation_view(map_view, annotation) end + def mapView(mapview, leftCalloutAccessoryViewForAnnotation: annotation) + if annotation.params[:left_action] + button_type = annotation.params[:left_action_button_type] || UIButtonTypeDetailDisclosure + action_button = UIButton.buttonWithType(button_type) + + action_button + else + annotation.left_accessory + end + end + + def mapView(mapview, rightCalloutAccessoryViewForAnnotation: annotation) + if annotation.params[:right_action] + button_type = annotation.params[:right_action_button_type] || UIButtonTypeDetailDisclosure + action_button = UIButton.buttonWithType(button_type) + action_button.tag = 1 + + action_button + else + annotation.right_accessory + end + end + + def mapView(mapView, annotation: annotation, calloutAccessoryControlTapped: accessory) + return nil unless annotation.params[:left_action] || annotation.params[:right_action] + if accessory.tag == 1 + self.send(annotation.params[:right_action]) + else + self.send(annotation.params[:left_action]) + end + end + ########## Cocoa touch methods ################# def mapView(map_view, didUpdateUserLocation:userLocation) if self.respond_to?(:on_user_location) on_user_location(userLocation) else @@ -384,26 +375,23 @@ elsif self.respond_to?(:on_change_region) on_change_region end end - def tapOnCalloutAccessoryControl(control, forAnnotation: annotation, onMap: map) - control.sendActionsForControlEvents(UIControlEventTouchUpInside) - end ########## Cocoa touch Ruby counterparts ################# - def deceleration_mode - map.decelerationMode + def type + map.mapType end - def deceleration_mode=(mode) - map.decelerationMode = mode + def type=(type) + map.mapType = type end - %w(dragging bouncing clustering).each do |meth| + %w(zoom scroll pitch rotate).each do |meth| define_method("#{meth}_enabled?") do - map.send("#{meth}Enabled") + map.send("is#{meth.capitalize}Enabled") end define_method("#{meth}_enabled=") do |argument| map.send("#{meth}Enabled=", argument) end @@ -435,24 +423,18 @@ end def get_tap_to_add @tap_to_add ||= false end - - # Mapbox setup - def mapbox_setup(params={}) - @mapbox_setup_params = params - @mapbox_setup = true + + def map_style(style) + @map_style_url = NSURL.URLWithString("asset://styles/#{style}.json") end - - def get_mapbox_setup_params - @mapbox_setup_params ||= nil + + def get_map_style + @map_style_url ||= map_style(:light) end - - def get_mapbox_setup - @mapbox_setup ||= false - end - + end def self.included(base) base.extend(MapClassMethods) end