Sök…
Lägg till MKMapView
Snabb
let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 320, height: 500))
Det rekommenderas att lagra mapView som en egenskap hos den innehållande ViewController
eftersom du kanske vill komma åt den i mer komplexa implementationer.
Mål C
self.map = [[MKMapView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:self.map];
Ändra karttyp
Det finns 5 olika typer ( MKMapType
), MKMapView
kan visas.
.satelliteFlyover
Visar en satellitbild av området med flyoverdata där det finns tillgängligt.
Snabb 2
mapView.mapType = .SatelliteFlyover
Snabb 3
mapView.mapType = .satelliteFlyover
Objective-C
_mapView.mapType = MKMapTypeSatelliteFlyover;
.hybridFlyover
Visar en hybrid-satellitbild med flyoverdata där det finns tillgängligt.
Snabb 2
mapView.mapType = .HybridFlyover
Snabb 3
mapView.mapType = .hybridFlyover
Objective-C
_mapView.mapType = MKMapTypeHybridFlyover;
Ställ in zoom / region för karta
För att ställa in en viss zoomnivå, låt oss säga att vi vill zooma användarens plats med användarplats som centrum och 2 km område som radie. Sedan använder vi följande kod
MKUserLocation *userLocation = _mapView.userLocation;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance (userLocation.location.coordinate, 2000, 2000);
[_mapView setRegion:region animated:NO];
Lokal sökimplementering med MKLocalSearch
MKLocalSearch gör det möjligt för användare att söka efter plats med naturliga språksträngar som "gym". När sökningen är klar returnerar klassen en lista över platser inom ett specifikt område som matchar söksträngen.
Sökresultaten är i form av MKMapItem inom MKLocalSearchResponse-objekt.
låt oss prova med exempel
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
I vissa fall kanske du inte vill använda standardkartorna, som Apple tillhandahåller.
Du kan lägga till en överläggning till din mapView
som innehåller anpassade brickor till exempel från OpenStreetMap .
Låt oss anta att self.mapView
är din MKMapView
som du redan har lagt till din ViewController
.
Först måste din ViewController
överensstämma med protokollet MKMapViewDelegate
.
class MyViewController: UIViewController, MKMapViewDelegate
Då måste du ställa in ViewController
som delegat för mapView
mapView.delegate = self
Därefter konfigurerar du överlägget för kartan. Du behöver en URL-mall för detta. Webbadressen bör likna den här på alla kakel-servrar och även om du skulle lagra kartdata offline: 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
När du har konfigurerat överläggningen måste du lägga till den i din mapView
.
mapView.add(overlay, level: .aboveLabels)
För att använda anpassade kartor rekommenderas att du använder .aboveLabels
för level
. Annars skulle standardetiketterna vara synliga på din anpassade karta. Om du vill se standardetiketterna kan du välja .aboveRoads
här.
Om du skulle köra ditt projekt nu känner du igen att kartan fortfarande skulle visa standardkartan:
Det beror på att vi inte har berättat för mapView
ännu, hur vi kan göra överläggningen. Detta är anledningen till varför du var tvungen att ställa in delegaten innan. Nu kan du lägga till func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
till din visningskontroller:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKTileOverlay {
let renderer = MKTileOverlayRenderer(overlay: overlay)
return renderer
} else {
return MKTileOverlayRenderer()
}
}
Detta returnerar rätt MKOverlayRenderer
till din mapView
. Om du kör ditt projekt nu bör du se en karta som denna:
Om du vill visa en annan karta måste du bara ändra URL-mallen. Det finns en lista med kakel-servrar i OSM Wiki.
Visa UserLocation och UserTracking-exempel
Detta visar användarens plats på kartan
Objective-C
[self.map setShowsUserLocation:YES];
Snabb
self.map?.showsUserLocation = true
Detta spårar användarnas plats på kartan och uppdaterar regionerna enligt
Objective-C
[self.map setUserTrackingMode:MKUserTrackingModeFollow];
Snabb
self.map?.userTrackingMode = .follow
Lägga till pin / point-kommentar på kartan
För att kommentera någon intressepunkt på kartan använder vi stiftantotering. Börja med att skapa anteckningsobjekt först.
MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc] init];
Ge nu koordinat till pointAnnotation, som
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(23.054625,72.534562);
pointAnnotation.coordinate = coordinate;
Ge nu titel och undertexter till kommentarerna,
pointAnnotation.title = @"XYZ Point";
pointAnnotation.subtitle = @"Ahmedabad Area";
Lägg nu till denna kommentar på kartan.
[self.mapView addAnnotation:pointAnnotation];
Yeaah ... Hurra ... du har gjort jobbet. Du kan nu se punktanteckningen (röd färgad stift) vid en given koordinat.
Men nu, om du vill ändra stiftets färg (3 tillgängliga färger är - lila, röda och gröna). Följ sedan detta steg.
ställa in Mapviews delegat till mig själv,
self.mapView.delegate = self;
Lägg till MKMapViewDelegate-implementering. Lägg nu till följande metod,
- (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;
}
Simulera en anpassad plats
Steg 1: I Xcode: File -> New -> File -> Resource -> GPX File -> Next -> Ge GPX-filen ett namn (det är Taipei
i det här exemplet) -> Skapa
Steg 2: Redigera GPX-filen
<?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>
Steg 3: När simulatorn körs:
Du kan upprepa den här processen för att skapa flera platser.
Bläddra för att koordinera och zooma nivå
När du visar en plats för dina användare kanske du vill att MKMapView
ska visa en koordinat på en zoomnivå istället för att ställa in en region som ska visas. Den här funktionen implementeras inte som standard, så du måste utöka MKMapView
med en metod som gör den komplexa beräkningen från en koordinat och zoomnivå till en 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)
}
}
}
(Den ursprungliga Swift 2-versionen av Mylene Bayan finns på GitHub )
När du har implementerat detta extension
kan du ställa in mittkoordinaten enligt följande:
let centerCoordinate = CLLocationCoordinate2DMake(48.136315, 11.5752901) //latitude, longitude
mapView?.setCenter(centerCoordinate, zoomLevel: 15, animated: true)
zoomLevel
är en Double
värde, vanligtvis mellan 0
och 21
(som är en mycket kraftfull zoom-nivå), men värden upp till 28
är tillåtna.
Arbeta med kommentarer
Få alla kommentarer
//following method returns all annotations object added on map
NSArray *allAnnotations = mapView.annotations;
Få kommentarvy
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"];
}
}
Ta bort alla kommentarer
[mapView removeAnnotations:mapView.annotations]
Ta bort en enda kommentar
//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];
}
Justera kartvyens synliga rekt för att visa alla kommentarer
Snabb:
mapView.showAnnotations(mapView.annotations, animated: true)
Objective-C:
[mapView showAnnotations:mapView.annotations animated:YES];
demo: