9
votes

Affichage mkmapViewnotations dans une carte Vue Visible

J'affiche un MKMapView à l'intérieur d'un en-tête de vue de table de parallaxe de style chemin de chemin. Pour créer l'effet, les limites MapView sont plus grandes que la zone visible à l'utilisateur. Je dois définir la région de la carte de manière à ce que toutes les annotations de la carte soient contenues dans le record Visible de MKMAPView. Quelle est la meilleure façon de faire cela?

mkmapview avec zone visible limitée

Modifier pour plus de clarté: Voici un cas d'utilisation. La taille MAPView est de 320 x 380. La zone visible est toutefois définie par le rect (0,0, 20,0, 320.0, 100,0). J'ai besoin de définir la région de sorte que toutes les annotations apparaissent dans ce nouveau dans la carte .View.


0 commentaires

7 Réponses :


-1
votes

Essayez de recevoir de la valeur de vos bords d'annotation (max et min) pour LAN et LON.

Définissez cette valeur au début: p> xxx pré>

puis utilisez Cette fonction permet de calculer la portée et la région: p> xxx pré>

et utilisez-le dans la mode ViewDidLoad Méthode: P>

-(void)viewDidLoad
{
    [super viewDidLoad];
    [self zoomAndFit];
}


3 commentaires

Ce code correspond à toutes les annotations des limites du MapView, mais ce dont j'ai besoin, c'est d'adapter toutes les annotations d'un CGRRECT donné dans les limites du MapView.


@ user2393462435 Ce n'est pas clairement ce que vous essayez exactement de dire ... Lisez-le vous-même et soyez clair dans ce que vous demandez.


@ R.A La taille MAPView est de 320 x 380. Définissez la région de la carte de la carte de manière à ce que toutes les annotations se situent dans la section record (0,0, 20,0, 320.0, 100.0). C'est ça.



0
votes

Si vous êtes prêt à se rapprocher des calculs, vous pouvez le faire en utilisant une échelle intelligente.

Votre zone cible est de 80 grandes sur une carte de 380. Par conséquent, vous voulez une région de 4,75x plus grande que la région calculée pour répondre à vos annotations. (0,25 extra ci-dessus et 3,5 supplémentaires ci-dessous).

Tout d'abord, vous devez obtenir une région (ou mapprect, que vous préférez travailler dans) et en faire les mêmes proportions que votre zone visible cibles. En effet, une région très large et courte ne toucherait pas le haut et le bas de la zone visible et de multiplier ainsi sa hauteur ne ferait pas quelque chose qui a touché le haut et le bas de votre vision de carte. Donc, si visible_height / visible_width> annotations_height / annotations_width Vous devez définir le annotations_height sur annotations_width * (visible_height / visible_width) . .

Avec cela, vous ajoutez ensuite 25% sur le nord de la boîte d'annotations et 350% sur le sud. Vous pouvez le faire en déplaçant le centre 212,5% (de la hauteur actuelle) vers le sud et augmentant la portée verticale de 475%.

Maintenant, tout cela est une approximation étant donné que le monde est sphère et que nous ne regardons pas une projection plane (c'est-à-dire 1 degré de latitude près de l'équateur est tiré de plus de 1 degré près des pôles). Mais si vous voulez bien être précis, vous pourriez rechercher les chiffres en fonction de la latitude et de telle. Si vous ne faites que traiter avec des annotations sur une échelle de la taille d'une ville, vous serez probablement bien.

espère que cela aide.


0 commentaires

0
votes

Si vous souhaitez trouver les annotations figurant dans un record donné:

- (void)assureAnnotationViewsAreVisible:(NSArray*)annotations originalRegion:(MKCoordinateRegion)originalRegion {
    CGFloat smallestX = MAXFLOAT;
    CGFloat smallestY = MAXFLOAT;
    CGFloat biggestX = -100;
    CGFloat biggestY = -100;

    //NSLog(@"---: %d", annotations.count);
    for(id<MKAnnotation> *annotation in annotations) {
        UIView *annotationView = [self.mapView viewForAnnotation:v];

        CGRect annotationViewFrame = annotationView.bounds;
        annotationViewFrame.origin = [self.mapView convertCoordinate:annotationView.coordinate toPointToView:self.mapView];
        annotationViewFrame.origin = CGPointMake(annotationViewFrame.origin.x-annotationViewFrame.size.width/2,
                                                 annotationViewFrame.origin.y-annotationViewFrame.size.height);

        smallestX = MIN(annotationViewFrame.origin.x, smallestX);
        smallestY = MIN(annotationViewFrame.origin.y, smallestY);
        biggestX = MAX(annotationViewFrame.origin.x+annotationViewFrame.size.width, biggestX);
        biggestY = MAX(annotationViewFrame.origin.y+annotationViewFrame.size.height, biggestY);
    }
    //NSLog(@"---");

    CGRect bounds = self.mapView.bounds;
    if(smallestX < bounds.origin.x || smallestY < bounds.origin.y || biggestX > bounds.origin.x+bounds.size.width || biggestY > bounds.origin.y+bounds.size.height) {
        CGRect neededRect = bounds;
        neededRect.origin = CGPointMake(MIN(bounds.origin.x, smallestX), MIN(bounds.origin.y, smallestY));
        neededRect.size = CGSizeMake(MAX(bounds.size.width, biggestX), MAX(bounds.size.height, biggestY));

        MKCoordinateRegion neededRegion = [self.mapView convertRect:neededRect toRegionFromView:self.mapView];
        _ignoreRegionChange = YES;
        [self.mapView setRegion:originalRegion animated:NO];
        _ignoreRegionChange = NO;
        [self.mapView setRegion:neededRegion animated:YES];
    }
    else {
        MKCoordinateRegion currentRegion = self.mapView.region;
        _ignoreRegionChange = YES;
        [self.mapView setRegion:originalRegion animated:NO];
        _ignoreRegionChange = NO;
        [self.mapView setRegion:currentRegion animated:YES];
    }
}


3 commentaires

Où les allonances dans un Nsarray avec les annotations que vous avez (sur la carte ou non)


Quelle est la valeur de maxfloat?


ne sais pas. Il s'agit d'une valeur définie spécifique de plate-forme / d'arche / OS .. Laissez-le dire que c'est ~ 32000



18
votes

Réglage de la région de la carte afin que toutes les annotations soient contenues dans une certaine partie d'un mkmapview peut être effectuée en trois étapes. L'entrée est le mapviev et le annotationsframe .

  1. Calculez un mkmaprect maprect contenant toutes les annotations.
  2. Calculez les embarcations d'embarquement de MapView.bounds et AnnotationsFrame .
  3. Call -sevissiblemaprect: EdgePadding: Animation: sur la vue Carte.

    ci-dessous est un coup d'écran d'un test. La superposition rouge indique le

    coup d'écran d'un test montrant que toutes les annotations sont à l'intérieur du cadre d'annotation donné

    voici le code. méfiez : c'est tout dans une méthode de simplification de l'ajout à votre code, et il n'est pas testé pour les cas de bord comme passer dans n annotations avec la même coordonnée ou avoir le Annotations si éloignées que la carte devrait être trop zoomée, ou avoir des coordonnées qui s'étendent au bord de la carte à +/- 180 degrés longitude. xxx

    si Vous allez pour un placement parfait (et qui ne le fait pas), voici trois choses à considérer:

    1. Le code assure que toutes les coordonnées sont dans le AnnotationsFrame , mais les annotations elles-mêmes peuvent être à l'extérieur. Pour éviter cela, utilisez simplement plus de rembourrage. Par exemple, si vos annotations sont 20x20 et centrées sur la coordonnée, utilisez 10 autres remplissages de tous les côtés.
    2. ci-dessous iOS 7, la carte n'était pas zoom sur l'échelle de zoom parfaite, mais à la taille de la tuile suivante (puissance de deux). Donc, il y aura plus d'espace autour des annotations que nécessaire, comme indiqué sur la capture d'écran.
    3. sur iOS 7, la vue Carte sera non seulement zoomer parfaitement, mais se soucie automatiquement de la barre d'état. Pour effectuer le calcul correct, vous devez soustraire la hauteur de la barre d'état à partir du remplissage supérieur sur iOS 7.

0 commentaires

6
votes

Partir de iOS 7.0, cela peut être facilement réalisé avec montrophanotations code>.

Swift: p> xxx pré>

objectif-c: p >

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


3 commentaires

@ kishan94 utilisez-vous Swift ou Objective-C?


Le code que j'ai écrit avant est pour Swift. J'ai ajouté un exemple de code pour Objective-C, veuillez vérifier.


Ok +1 ajouté, désolé, je n'ai pas essayé à Swift ... @andree



0
votes

Vous devez d'abord ajouter les annotations: (Bien sûr, cela est après avoir déjà eu une liste d'annotations)

swift4: p> blockQuote> xxx pré>

Vous pouvez utiliser la constante CurrentView ou placer directement le mkmaprect comme tel: ci-dessous: (.VisiblemapRect Retours: P>

"La zone actuellement affichée par le Affichage de la carte. " P>

mapView.annotations(in: mapView.visibleMapRect)


0 commentaires

0
votes

J'ai trouvé un moyen plus facile sans calculer est de laisser la vue Carte le calculer, puis nous ajustons les bords.

//1: Show all annotation on the map view, but without animation
self.mapView.showAnnotations(self.mapView.annotations, animated: false)

//2: Get the current visible map rect
let currentMapRect = self.mapView.visibleMapRect

//3: Create the edges inset that you want the map view to show all annotation within
let padding = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100)

//4: Set current map rect but with new padding, also set animation to true to see effect
self.mapView.setVisibleMapRect(currentMapRect, edgePadding: padding, animated: true)


0 commentaires