如何在地图视图xamarin iOS上绘制从当前位置到目的地位置的路线

时间:2014-08-31 17:15:44

标签: c# ios xamarin mkmapview maproute

如何从当前位置到目的地位置绘制路线图。 我想从我当前的位置(即设备GPS位置)在mapview上绘制路线图。到目的地{d}

using System;
using System.Drawing;
using MonoTouch.CoreLocation;
using MonoTouch.MapKit;
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using System.Security.Cryptography.X509Certificates;

namespace IOS {

    public class MapViewController : UIViewController {

        MKMapView mapView;
        UIView  customHeader;
        UIButton btn_Back;
        UISegmentedControl  mapTypes;

        public  float destinationLatitude = 0.0f, destinationLongitude = 0.0f;
        public string storeName = "N.A.";
        public string storeLocation = "N.A.";


        public MapViewController (){       
            mapView = new MKMapView (); 
            mapView.AutoresizingMask = UIViewAutoresizing.FlexibleDimensions;       
            mapView.Frame = new RectangleF (0, 60, View.Frame.Size.Width, View.Frame.Size.Height);


            int typesWidth=260, typesHeight=30, distanceFromBottom=60;
            mapTypes = new UISegmentedControl(new RectangleF((View.Bounds.Width-typesWidth)/2, View.Bounds.Height-distanceFromBottom, typesWidth, typesHeight));
            mapTypes.InsertSegment("Road", 0, false);
            mapTypes.InsertSegment("Satellite", 1, false);
            mapTypes.InsertSegment("Hybrid", 2, false);
            mapTypes.InsertSegment ("Direction",3,false);
            mapTypes.SelectedSegment = 0; // Road is the default
            mapTypes.AutoresizingMask = UIViewAutoresizing.FlexibleTopMargin;
            mapTypes.ValueChanged += (s, e) => {

                switch(mapTypes.SelectedSegment) {
                case 0:
                    mapView.MapType = MKMapType.Standard;
                    break;
                case 1:
                    mapView.MapType = MKMapType.Satellite;
                    break;
                case 2:
                    mapView.MapType = MKMapType.Hybrid;
                    break;
                case 3:
                    Console.WriteLine ("drawing route");
                    break;
                }
            };

            View.AddSubview(mapView);
            View.AddSubview (mapTypes); 

        }

        public override void ViewDidLoad (){
            base.ViewDidLoad ();
            Title = "Store Location";
        }

        public override void ViewWillAppear (bool animated){
            base.ViewWillAppear (animated);
            var coords = new CLLocationCoordinate2D(destinationLatitude, destinationLongitude);
            var span = new MKCoordinateSpan(MilesToLatitudeDegrees (2), MilesToLongitudeDegrees (2, coords.Latitude));
            // set the coords and zoom on the map
            mapView.Region = new MKCoordinateRegion (coords, span);
            // assign the delegate, which handles annotation layout and clicking
            mapView.Delegate = new MapDelegate();
            // add a basic annotation
            var annotation = new BasicMapAnnotation (new CLLocationCoordinate2D (destinationLatitude, destinationLongitude), "StoreName", storeLocation);
            mapView.AddAnnotation (annotation); 

        }

        /// <summary>
        /// Converts miles to latitude degrees
        /// </summary>
        public double MilesToLatitudeDegrees(double miles){

            double earthRadius = 3960.0;
            double radiansToDegrees = 180.0/Math.PI;
            return (miles/earthRadius) * radiansToDegrees;
        }

        /// <summary>
        /// Converts miles to longitudinal degrees at a specified latitude
        /// </summary>
        public double MilesToLongitudeDegrees(double miles, double atLatitude)
        {
            double earthRadius = 3960.0;
            double degreesToRadians = Math.PI/180.0;
            double radiansToDegrees = 180.0/Math.PI;

            // derive the earth's radius at that point in latitude
            double radiusAtLatitude = earthRadius * Math.Cos(atLatitude * degreesToRadians);
            return (miles / radiusAtLatitude) * radiansToDegrees;
        }


        // The map delegate is much like the table delegate.
        protected class MapDelegate : MKMapViewDelegate{
            protected string annotationIdentifier = "BasicAnnotation";
            UIButton detailButton;
            /// <summary>
            /// This is very much like the GetCell method on the table delegate
            /// </summary>
            public override MKAnnotationView GetViewForAnnotation (MKMapView mapView, NSObject annotation)
            {
                // try and dequeue the annotation view
                MKAnnotationView annotationView = mapView.DequeueReusableAnnotation(annotationIdentifier);

                // if we couldn't dequeue one, create a new one
                if (annotationView == null)
                    annotationView = new MKPinAnnotationView(annotation, annotationIdentifier);
                else // if we did dequeue one for reuse, assign the annotation to it
                    annotationView.Annotation = annotation;

                // configure our annotation view properties
                annotationView.CanShowCallout = true;
                (annotationView as MKPinAnnotationView).AnimatesDrop = true;
                (annotationView as MKPinAnnotationView).PinColor = MKPinAnnotationColor.Green;
                annotationView.Selected = true;

                // you can add an accessory view, in this case, we'll add a button on the right, and an image on the left
                detailButton = UIButton.FromType(UIButtonType.DetailDisclosure);

                detailButton.TouchUpInside += (s, e) => { 
                    Console.WriteLine ("Clicked");
                    new UIAlertView("Annotation Clicked", "You clicked on " +
                        (annotation as MKAnnotation).Coordinate.Latitude.ToString() + ", " +
                        (annotation as MKAnnotation).Coordinate.Longitude.ToString() , null, "OK", null).Show(); 
                };
                annotationView.RightCalloutAccessoryView = detailButton;
//              annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromBundle("29_icon.png"));
                return annotationView;
            }
            // as an optimization, you should override this method to add or remove annotations as the 
            // map zooms in or out.
            public override void RegionChanged (MKMapView mapView, bool animated) {}
        }

        protected class BasicMapAnnotation : MKAnnotation
        {
            /// <summary>
            /// The location of the annotation
            /// </summary>
            public override CLLocationCoordinate2D Coordinate { get; set; }
            protected string title;
            protected string subtitle;

            /// <summary>
            /// The title text
            /// </summary>
            public override string Title
            { get { return title; } }


            /// <summary>
            /// The subtitle text
            /// </summary>
            public override string Subtitle
            { get { return subtitle; } }

            public BasicMapAnnotation (CLLocationCoordinate2D coordinate, string title, string subTitle)
                : base()
            {
                this.Coordinate = coordinate;
                this.title = title;
                this.subtitle = subTitle;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我正在使用this tutorial,这实际上是说它是从MKDirections对象调用CalculateDirections。作为参考,这是Davidson Blake的代码:

使用MonoTouch.MapKit; 使用MonoTouch.CoreLocation;

//in class:
private MKMapView _map;
private MKMapViewDelegate _mapDelegate;

 public override void ViewDidLoad()        {
            base.ViewDidLoad();

            //Init Map
            _map = new MKMapView
            {
                MapType = MKMapType.Standard,
                ShowsUserLocation = true,
                ZoomEnabled = true,
                ScrollEnabled = true
            };

            //Create new MapDelegate Instance
            _mapDelegate = new MapDelegate();

            //Add delegate to map
            _map.Delegate = _mapDelegate;

            View = _map;

            //Create Directions
            CreateRoute();
        }

//in createroute
  //Create Origin and Dest Place Marks and Map Items to use for directions
            //Start at Xamarin SF Office
            var orignPlaceMark = new MKPlacemark(new CLLocationCoordinate2D(37.797530, -122.402590), null);
            var sourceItem = new MKMapItem(orignPlaceMark);

            //End at Xamarin Cambridge Office
            var destPlaceMark = new MKPlacemark(new CLLocationCoordinate2D(42.374172, -71.120639), null);
            var destItem = new MKMapItem(destPlaceMark);
var request = new MKDirectionsRequest
            {
                Source = sourceItem,
                Destination = destItem,
                RequestsAlternateRoutes = true
            };

            var directions = new MKDirections(request);

 directions.CalculateDirections((response, error) =>
            {
                if (error != null)
                {
                    Console.WriteLine(error.LocalizedDescription);
                }
                else
                {
                   //Add each Polyline from route to map as overlay
                    foreach (var route in response.Routes)
                    {
                        _map.AddOverlay(route.Polyline);
                    }
                }
            });

class MapDelegate : MKMapViewDelegate
  {
        //Override OverLayRenderer to draw Polyline from directions
        public override MKOverlayRenderer OverlayRenderer(MKMapView mapView, IMKOverlay overlay)
            {
                if (overlay is MKPolyline)
                {
                    var route = (MKPolyline)overlay;
                    var renderer = new MKPolylineRenderer(route) { StrokeColor = UIColor.Blue };
                    return renderer;
                }
                return null;
            }
        }

    }