Zoeken…
Voeg MKMapView toe
Snel
let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 320, height: 500))
Het wordt aanbevolen om de mapView op te slaan als een eigenschap van de bevattende ViewController
omdat u er mogelijk toegang toe wilt hebben in complexere implementaties.
Doelstelling C
self.map = [[MKMapView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:self.map];
Wijzig het kaarttype
Er zijn 5 verschillende typen ( MKMapType
) die MKMapView
kan weergeven.
.satelliteFlyover
Toont een satellietbeeld van het gebied met flyover-gegevens, indien beschikbaar.
Swift 2
mapView.mapType = .SatelliteFlyover
Swift 3
mapView.mapType = .satelliteFlyover
Doelstelling C
_mapView.mapType = MKMapTypeSatelliteFlyover;
.hybridFlyover
Toont een hybride satellietbeeld met flyover-gegevens indien beschikbaar.
Swift 2
mapView.mapType = .HybridFlyover
Swift 3
mapView.mapType = .hybridFlyover
Doelstelling C
_mapView.mapType = MKMapTypeHybridFlyover;
Zoom / regio instellen voor kaart
Om een zoomniveau in te stellen, laten we zeggen dat we de locatie van de gebruiker willen zoomen met de gebruikerslocatie als middelpunt en 2 km gebied als straal. Vervolgens gebruiken we de volgende code
MKUserLocation *userLocation = _mapView.userLocation;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance (userLocation.location.coordinate, 2000, 2000);
[_mapView setRegion:region animated:NO];
Lokale zoekimplementatie met behulp van MKLocalSearch
MKLocalSearch stelt gebruikers in staat om naar locatie te zoeken met behulp van natuurlijke taalreeksen zoals "gym". Nadat de zoekopdracht is voltooid, retourneert de klasse een lijst met locaties binnen een opgegeven regio die overeenkomen met de zoekreeks.
Zoekresultaten hebben de vorm van MKMapItem binnen het MKLocalSearchResponse-object.
laten we het eens proberen
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
In sommige gevallen wilt u misschien niet de standaardkaarten gebruiken, biedt Apple.
U kunt een overlay aan uw mapView
die aangepaste tegels bevat, bijvoorbeeld van OpenStreetMap .
Laten we aannemen dat self.mapView
uw MKMapView
die u al aan uw ViewController
hebt toegevoegd.
Eerst moet uw ViewController
voldoen aan het protocol MKMapViewDelegate
.
class MyViewController: UIViewController, MKMapViewDelegate
Vervolgens moet u de ViewController
als gemachtigde van mapView
mapView.delegate = self
Vervolgens configureert u de overlay voor de kaart. Hiervoor heeft u een URL-sjabloon nodig. De URL moet op alle tegelservers hetzelfde zijn en zelfs als u de kaartgegevens offline zou opslaan: 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
Nadat u de overlay hebt geconfigureerd, moet u deze aan uw mapView
.
mapView.add(overlay, level: .aboveLabels)
Om aangepaste kaarten te gebruiken, wordt aanbevolen om .aboveLabels
voor level
. Anders zouden de standaardlabels zichtbaar zijn op uw aangepaste kaart. Als u de standaardlabels wilt zien, kunt u hier .aboveRoads
kiezen.
Als u uw project nu zou uitvoeren, zou u herkennen dat uw kaart nog steeds de standaardkaart zou tonen:
Dat komt omdat we de mapView
nog niet hebben verteld hoe de overlay moet worden weergegeven. Dit is de reden waarom u de gedelegeerde eerder moest instellen. Nu kunt u func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
aan uw weergavecontroller:
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKTileOverlay {
let renderer = MKTileOverlayRenderer(overlay: overlay)
return renderer
} else {
return MKTileOverlayRenderer()
}
}
Dit zal de juiste terug MKOverlayRenderer
naar uw mapView
. Als u uw project nu uitvoert, zou u een kaart als deze moeten zien:
Als u een andere kaart wilt weergeven, moet u alleen de URL-sjabloon wijzigen. Er is een lijst met tegelservers in de OSM Wiki.
Toon UserLocation en UserTracking-voorbeeld
Dit toont de gebruikerslocatie op de kaart
Doelstelling C
[self.map setShowsUserLocation:YES];
Snel
self.map?.showsUserLocation = true
Hiermee wordt de gebruikerslocatie op de kaart gevolgd en worden de regio's bijgewerkt
Doelstelling C
[self.map setUserTrackingMode:MKUserTrackingModeFollow];
Snel
self.map?.userTrackingMode = .follow
Pin- / puntaantekening op de kaart toevoegen
Voor het annoteren van een interessant punt op de kaart gebruiken we pin annotatie. Begin nu eerst met het maken van een annotatieobject.
MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc] init];
Geef nu coördinaten aan pointAnnotation als
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(23.054625,72.534562);
pointAnnotation.coordinate = coordinate;
Geef nu de titel en ondertiteling van annotatie,
pointAnnotation.title = @"XYZ Point";
pointAnnotation.subtitle = @"Ahmedabad Area";
Voeg nu deze annotatie toe aan de kaart.
[self.mapView addAnnotation:pointAnnotation];
Yeaah ... Hoera ... je hebt het gedaan. U kunt nu puntaantekening (rood gekleurde pin) zien op gegeven coördinaat.
Maar nu, wat als u de kleur van de pin wilt veranderen (3 beschikbare kleuren zijn - Paars, rood en groen). Volg dan deze stap.
zet de gemachtigde van mapview op zichzelf,
self.mapView.delegate = self;
Implementatie van MKMapViewDelegate toevoegen. Voeg nu de volgende methode toe,
- (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;
}
Simuleer een aangepaste locatie
Stap 1: In Xcode: Bestand -> Nieuw -> Bestand -> Bron -> GPX-bestand -> Volgende -> Geef het GPX-bestand een naam (dit is Taipei
in dit voorbeeld) -> Maken
Stap 2: Bewerk het GPX-bestand
<?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>
Stap 3: Wanneer de simulator actief is:
U kunt dit proces herhalen om meerdere locaties te maken.
Scroll om te coördineren en zoomniveau
Wanneer u een locatie aan uw gebruikers toont, wilt u misschien dat de MKMapView
een coördinaat op zoomniveau weergeeft in plaats van een weer te geven regio in te stellen. Deze functionaliteit wordt niet standaard geïmplementeerd, dus u moet MKMapView
uitbreiden met een methode die de complexe berekening MKMapView
van een coördinaat en zoomniveau naar een 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)
}
}
}
(De originele Swift 2-versie van Mylene Bayan is te vinden op GitHub )
Nadat u deze extension
hebt geïmplementeerd, kunt u de middelste coördinaat als volgt instellen:
let centerCoordinate = CLLocationCoordinate2DMake(48.136315, 11.5752901) //latitude, longitude
mapView?.setCenter(centerCoordinate, zoomLevel: 15, animated: true)
zoomLevel
is een Double
waarde, meestal tussen 0
en 21
(wat een zeer hoog zoomniveau is), maar waarden tot 28
zijn toegestaan.
Werken met annotatie
Krijg alle annotaties
//following method returns all annotations object added on map
NSArray *allAnnotations = mapView.annotations;
Bekijk aantekeningenweergave
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"];
}
}
Verwijder alle annotaties
[mapView removeAnnotations:mapView.annotations]
Verwijder enkele annotatie
//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];
}
Pas de zichtbare rect van de kaartweergave aan om alle annotaties weer te geven
Snel:
mapView.showAnnotations(mapView.annotations, animated: true)
Doelstelling C:
[mapView showAnnotations:mapView.annotations animated:YES];
demo: