Поиск…


Добавить MKMapView

стриж

let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 320, height: 500))

Рекомендуется хранить mapView как свойство содержащего ViewController так как вы можете захотеть получить к нему доступ в более сложных реализациях.

Цель C

self.map = [[MKMapView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:self.map];

Изменить тип карты

Существует 5 различных типов ( MKMapType ), MKMapView может отображать.

iPhone OS 3

.Стандартный

Отображает карту улиц, в которой указаны позиции всех дорог и названия дорог.

Swift 2

mapView.mapType = .Standard

Swift 3

mapView.mapType = .standard

Objective-C

_mapView.mapType = MKMapTypeStandard;

Пример MKMapType.standard

iPhone OS 3

.спутник

Отображает спутниковые снимки области.

Swift 2

mapView.mapType = .Satellite

Swift 3

mapView.mapType = .satellite

Objective-C

_mapView.mapType = MKMapTypeSatellite;

Пример MKMapType.satellite

iOS 9

.satelliteFlyover

Отображает изображение спутника области с данными эстакады, если таковые имеются.

Swift 2

mapView.mapType = .SatelliteFlyover

Swift 3

mapView.mapType = .satelliteFlyover

Objective-C

_mapView.mapType = MKMapTypeSatelliteFlyover;
iPhone OS 3

.гибридный

Отображает изображение спутника области с информацией о названии дороги и дороги, расположенной сверху.

Swift 2

mapView.mapType = .Hybrid

Swift 3

mapView.mapType = .hybrid

Objective-C

_mapView.mapType = MKMapTypeHybrid;

Пример MKMapType.hybrid

iOS 9

.hybridFlyover

Отображает гибридное изображение спутника с данными эстакады, если таковые имеются.

Swift 2

mapView.mapType = .HybridFlyover

Swift 3

mapView.mapType = .hybridFlyover

Objective-C

_mapView.mapType = MKMapTypeHybridFlyover;

Установить масштаб / регион для карты

Чтобы установить некоторый уровень масштабирования, скажем, мы хотим увеличить местоположение пользователя с местоположением пользователя в центре и 2 км от площади в радиусе. Затем мы используем следующий код

MKUserLocation *userLocation = _mapView.userLocation;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance (userLocation.location.coordinate, 2000, 2000);
[_mapView setRegion:region animated:NO];

Реализация локального поиска с использованием MKLocalSearch

MKLocalSearch позволяет пользователям искать местоположение, используя строки естественного языка, такие как «тренажерный зал». Как только поиск будет завершен, класс возвращает список местоположений в пределах указанной области, которая соответствует строке поиска.

Результаты поиска в форме MKMapItem в объекте MKLocalSearchResponse.

попробуем попробовать

MKLocalSearchRequest *request = 
    [[MKLocalSearchRequest alloc] init];//initialising search request
request.naturalLanguageQuery = @”Gym”; // adding query
request.region = _mapView.region; //setting region
MKLocalSearch *search = 
     [[MKLocalSearch alloc]initWithRequest:request];//initiate search

[search startWithCompletionHandler:^(MKLocalSearchResponse 
     *response, NSError *error) 
{
   if (response.mapItems.count == 0)
       NSLog(@"No Matches");
   else
       for (MKMapItem *item in response.mapItems)
       {
           NSLog(@"name = %@", item.name);
           NSLog(@"Phone = %@", item.phoneNumber);
        }
}];

OpenStreetMap Tile-Overlay

В некоторых случаях вы, возможно, не захотите использовать карты по умолчанию, предоставляемые Apple.

Вы можете добавить наложение в свой mapView который содержит пользовательские плитки, например, из OpenStreetMap .

Предположим, self.mapView - это ваш MKMapView который вы уже добавили в свой ViewController .

Сначала ваш ViewController должен соответствовать протоколу MKMapViewDelegate .

class MyViewController: UIViewController, MKMapViewDelegate

Затем вы должны установить ViewController качестве делегата mapView

mapView.delegate = self

Затем вы настраиваете наложение для карты. Для этого вам понадобится шаблон URL. URL-адрес должен быть похож на это на всех серверах tile-серверов, и даже если вы сохраните данные карты в автономном режиме: http://tile.openstreetmap.org/{z}/{x}/{y}.png

let urlTeplate = "http://tile.openstreetmap.org/{z}/{x}/{y}.png"
let overlay = MKTileOverlay(urlTemplate: urlTeplate)
overlay.canReplaceMapContent = true

После настройки наложения вы должны добавить его в свой mapView .

mapView.add(overlay, level: .aboveLabels)

Чтобы использовать пользовательские карты, рекомендуется использовать .aboveLabels для level . В противном случае метки по умолчанию будут видны на вашей пользовательской карте. Если вы хотите увидеть метки по умолчанию, вы можете выбрать здесь .aboveRoads .

Если вы сейчас запустите свой проект, вы поймете, что ваша карта по-прежнему будет отображать карту по умолчанию:

первый забег. все еще отображается карта по умолчанию

Это потому, что мы еще не сказали mapView , как визуализировать наложение. Вот почему вы должны были установить делегат раньше. Теперь вы можете добавить func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer для вашего контроллера:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is MKTileOverlay {
        let renderer = MKTileOverlayRenderer(overlay: overlay)
        return renderer
    } else {
        return MKTileOverlayRenderer()
    }
}

Это вернет правильный MKOverlayRenderer в ваш mapView . Если вы запустите свой проект сейчас, вы должны увидеть такую ​​карту:

рабочая накладка OSM

Если вы хотите отобразить другую карту, вам просто нужно изменить шаблон URL. В Wiki OSM есть список tile-серверов .

Показать пример UserLocation и UserTracking

Это покажет местоположение пользователя на карте

Objective-C

[self.map setShowsUserLocation:YES];

стриж

self.map?.showsUserLocation = true

введите описание изображения здесь

Это позволит отслеживать местоположение пользователя на карте, обновлять регионы согласно

Objective-C

[self.map setUserTrackingMode:MKUserTrackingModeFollow];

стриж

self.map?.userTrackingMode = .follow

Добавление Pin / Point Annotation на карте

Для аннотации некоторой интересующей нас точки на карте мы используем pin-аннотацию. Теперь сначала создайте объект аннотации.

MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc] init];

Теперь предоставим координату pointAnnotation, так как

CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(23.054625,72.534562);
pointAnnotation.coordinate = coordinate;

Теперь укажите заголовок и субтитры для аннотации,

pointAnnotation.title = @"XYZ Point";
pointAnnotation.subtitle = @"Ahmedabad Area";

Теперь добавьте эту аннотацию к карте.

[self.mapView addAnnotation:pointAnnotation];

Да ... Ура. Ты сделал это. Теперь вы можете увидеть аннотацию точки (красный цветной контакт) при заданной координате.

Но теперь, если вы хотите изменить цвет штифта (3 доступных цвета - фиолетовый, красный и зеленый). Затем следуйте этому шагу.

назначить делегата mapview самому себе,

self.mapView.delegate = self;

Добавьте реализацию MKMapViewDelegate. Теперь добавьте следующий метод,

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    // If it's the user location, just return nil, because it have user location's own annotation, if you want to change that, then use this object;
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        //Use dequed pin if available
        MKAnnotationView *pinView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"PinAnnotationView"];
    
        if (!pinView)
        {
            // If not dequed, then create new.
            pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"PinAnnotationView"];
            pinView.canShowCallout = YES;
            pinView.image = [UIImage imageNamed:@"abc.png"];
            pinView.calloutOffset = CGPointMake(0, 32);
        } else {
            pinView.annotation = annotation;
        }
        return pinView;
    }
    return nil;
}

Имитировать настраиваемое местоположение

Шаг 1: В Xcode: Файл -> Создать -> Файл -> Ресурс -> Файл GPX -> Далее -> Дайте GPX-файлу имя (это в этом примере Taipei ) -> Создать

Шаг 2. Редактирование файла GPX.

<?xml version="1.0"?>
<gpx version="1.1" creator="Xcode">
    <wpt lat="25.041865" lon="121.551361"> // Edit the latitude and longitude 
        <name>Taipei</name> // Edit the name of the location
        <time>2014-09-24T14:55:37Z</time>
    </wpt>
</gpx>

Шаг 3: Когда симулятор запущен:

введите описание изображения здесь

Вы можете повторить этот процесс для создания нескольких местоположений.

Выделите координаты и масштаб

Когда вы показываете местоположение своим пользователям, вы можете захотеть, чтобы MKMapView отображал координату на уровне масштабирования, а не настраивал регион для отображения. Эта функциональность не реализована по умолчанию, поэтому вам необходимо расширить MKMapView с помощью методов, которые выполняют комплексный расчет с координаты и уровня масштабирования до MKCoordinateRegion .

let MERCATOR_OFFSET = 268435456.0
let MERCATOR_RADIUS = 85445659.44705395
let DEGREES = 180.0

public extension MKMapView {
    
    //MARK: Map Conversion Methods
    
    private func longitudeToPixelSpaceX(longitude:Double)->Double{
        return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / DEGREES)
    }
    
    private func latitudeToPixelSpaceY(latitude:Double)->Double{
        return round(MERCATOR_OFFSET - MERCATOR_RADIUS * log((1 + sin(latitude * M_PI / DEGREES)) / (1 - sin(latitude * M_PI / DEGREES))) / 2.0)
    }
    
    private func pixelSpaceXToLongitude(pixelX:Double)->Double{
        return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * DEGREES / M_PI
    }
    
    private func pixelSpaceYToLatitude(pixelY:Double)->Double{
        return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * DEGREES / M_PI
    }
    
    private func coordinateSpanWithCenterCoordinate(centerCoordinate:CLLocationCoordinate2D, zoomLevel:Double)->MKCoordinateSpan{
        // convert center coordiate to pixel space
        let centerPixelX = longitudeToPixelSpaceX(longitude: centerCoordinate.longitude)
        let centerPixelY = latitudeToPixelSpaceY(latitude: centerCoordinate.latitude)
        print(centerCoordinate)
        // determine the scale value from the zoom level
        let zoomExponent:Double = 20.0 - zoomLevel
        let zoomScale:Double = pow(2.0, zoomExponent)
        // scale the map’s size in pixel space
        let mapSizeInPixels = self.bounds.size
        let scaledMapWidth = Double(mapSizeInPixels.width) * zoomScale
        let scaledMapHeight = Double(mapSizeInPixels.height) * zoomScale
        // figure out the position of the top-left pixel
        let topLeftPixelX = centerPixelX - (scaledMapWidth / 2.0)
        let topLeftPixelY = centerPixelY - (scaledMapHeight / 2.0)
        // find delta between left and right longitudes
        let minLng = pixelSpaceXToLongitude(pixelX: topLeftPixelX)
        let maxLng = pixelSpaceXToLongitude(pixelX: topLeftPixelX + scaledMapWidth)
        let longitudeDelta = maxLng - minLng
        let minLat = pixelSpaceYToLatitude(pixelY: topLeftPixelY)
        let maxLat = pixelSpaceYToLatitude(pixelY: topLeftPixelY + scaledMapHeight)
        let latitudeDelta = -1.0 * (maxLat - minLat)
        return MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)
    }
    
    /**
     Sets the center of the `MKMapView` to a `CLLocationCoordinate2D` with a custom zoom-level. There is no nee to set a region manually. :-)
     
     - author: Mylene Bayan (on GitHub)
     */
    public func setCenter(_ coordinate:CLLocationCoordinate2D, zoomLevel:Double, animated:Bool){
        // clamp large numbers to 28
        var zoomLevel = zoomLevel
        zoomLevel = min(zoomLevel, 28)
        // use the zoom level to compute the region
        print(coordinate)
        let span = self.coordinateSpanWithCenterCoordinate(centerCoordinate: coordinate, zoomLevel: zoomLevel)
        let region = MKCoordinateRegionMake(coordinate, span)
        if region.center.longitude == -180.00000000{
            print("Invalid Region")
        }
        else{
            self.setRegion(region, animated: animated)
        }
    }
}

(Оригинальную версию Swift 2 от Mylene Bayan можно найти на GitHub )

После того, как вы внесете это extension , вы можете установить центральную координату следующим образом:

let centerCoordinate = CLLocationCoordinate2DMake(48.136315, 11.5752901) //latitude, longitude
mapView?.setCenter(centerCoordinate, zoomLevel: 15, animated: true)

zoomLevel - это Double значение, обычно от 0 до 21 (что является очень высоким уровнем масштабирования), но допустимы значения до 28 .

Работа с аннотацией

Получить всю аннотацию

//following method returns all annotations object added on map
NSArray *allAnnotations = mapView.annotations;

Просмотр аннотаций

for (id<MKAnnotation> annotation in mapView.annotations)
{
    MKAnnotationView* annotationView = [mapView viewForAnnotation:annotation];
    if (annotationView)
    {
       // Do something with annotation view 
       // for e.g change image of annotation view
       annotationView.image = [UIImage imageNamed:@"SelectedPin.png"];
    }
}

Удалить все аннотации

[mapView removeAnnotations:mapView.annotations]

Удалить отдельную аннотацию

//getting all Annotation
NSArray *allAnnotations = self.myMapView.annotations;

if (allAnnotations.count > 0)
{
    //getting first annoation
    id <MKAnnotation> annotation=[allAnnotations firstObject];
    
    //removing annotation
    [mapView removeAnnotation:annotation];
    
}

Отрегулируйте видимый прямоугольник вида карты, чтобы отобразить все аннотации

Swift:

mapView.showAnnotations(mapView.annotations, animated: true)

Objective-C:

[mapView showAnnotations:mapView.annotations animated:YES];

Демо-версия:

введите описание изображения здесь



Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow