Mapview, zoom to fit all annotations on screen

Hi there,


is there a way to zoom a mapview until all annotations are in view?

I found a piece of code that generates a region with min / max boundaries for all annotations. I managed to translate it into pascal, but I failed  to translate the line in bold. How would I do this with the mapview?

    MKCoordinateRegion region;
    region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
    region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
    region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1;

    // Add a little extra space on the sides
    region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1;

    region = [mapView regionThatFits:region];

    [mapView setRegion:region animated:YES];

Hi, 


You should be able to access regionThatFits with:

  TMSFMXNativeMKMapView1.MapView.regionThatFits()

Kind Regards,
Pieter

Hi Jan !

Could u show me how it's done to fit all annotations in view ?

@ Pieter, do i need only the "RegionthatFits", or also translated code from Jan
to get this working ?

Any example is welcome.

Cheers !




Hi,



You also need to have the code, I will look into this

and provide a small sample later today



Regards,

Pieter

Hi, 


I have created a small sample that sets the region to fit all annotations in view.
If you need a smaller / larger area (for example an offset), you need to decrease / increase the span
You also need to add the FMX.TMSNativeUICore unit for the MKCoordinateRegion record

procedure TForm913.ZoomToFit;
var
  maxCoord: TTMSFMXNativeMKMapLocation;
  minCoord: TTMSFMXNativeMKMapLocation;
  coord: TTMSFMXNativeMKMapLocation;
  I: Integer;
  rgnm: MKCoordinateRegion;
begin
  maxCoord.Latitude := -90;
  maxCoord.Longitude := -180;
  minCoord.Latitude := 90;
  minCoord.Longitude := 180;

  for I := 0 to TMSFMXNativeMKMapView1.Annotations.Count - 1 do
  begin
    coord := TMSFMXNativeMKMapView1.Annotations[ I ].Location;
    if coord.Longitude > maxCoord.Longitude then
      maxCoord.Longitude := coord.Longitude;

    if coord.Latitude > maxCoord.Latitude then
      maxCoord.Latitude := coord.Latitude;

    if coord.Longitude < minCoord.Longitude then
      minCoord.Longitude := coord.Longitude;

    if coord.Latitude < minCoord.Latitude then
      minCoord.Latitude := coord.Latitude;
  end;

  rgnm.center.longitude := (minCoord.Longitude + maxCoord.Longitude) / 2;
  rgnm.center.latitude := (minCoord.Latitude + maxCoord.Latitude) / 2;
  rgnm.span.longitudeDelta := maxCoord.Longitude - minCoord.Longitude;
  rgnm.span.latitudeDelta := maxCoord.Latitude - minCoord.Latitude;

  TMSFMXNativeMKMapView1.MapView.setRegion(rgnm, True);
end;

Kind Regards, 
Pieter

Pieter Scheldeman2013-07-03 08:28:30

Wouldn't it be a wonderfull addition to include a "zoomtoannotations" method to the mapview? ;-)

Is added and will be available in the next release


Regards, 
Pieter


While we are at it: there is a method named "removeallannotations", but this also deletes the current user location, if this property is set. When updating a map with custom annotations this is not what you want. Following code will remove all annotations save the user location:



    for Idx := aMapView.Annotations.Count -1 downto 0 do
    begin

    if not (IInterface(aMapView.Annotations[Idx].Annotation) = IInterface(aMapView.MapView.userLocation)) then
        aMapView.RemoveAnnotation(aMapView.Annotations[Idx]);
    end;

Hi, 


Thanks for the suggestion, we have fixed this here and are currently reuploading the new version.

Kind Regards, 
Pieter

Hi Pieter,

Thanks for your reply.

When i use the code i get this error :

Undeclared identifier: 'Location'

coord := TMSFMXNativeMKMapView1.Annotations.Location;

Am i missing something ?

Cheers.

Paul

you need to add the Index with Annotations[ I ].Location but the forum doesn't allow me to add brackets without spacesPieter Scheldeman2013-07-03 07:49:43

I Actually tested this here and it seems that you do not need the regionthatfits function, you can test with and without it and verify what best suits your needs.


Kind Regards, 
Pieter

Thanks Pieter !

Cheers

Hi Pieter,

I must be doing something wrong.

When i use the code, or when i use "ZoomToFitAnnotations", the map
will zoom to a place close to London, while i'm in Holland, so are all my
Annotations.

( I've downloaded the update)

Any clue ?

Cheers

rgnm.center.latitude := (minCoord.Longitude + maxCoord.Longitude) / 2;
  rgnm.center.latitude := (minCoord.Latitude + maxCoord.Latitude) / 2;

there is a bug in this line, first line should be rgnm.center.longitude = .....

Hi Jan,

Thanks !

Works now :)

Cheers

Thanks for the fix, modified the post

And reuploaded the latest version with the fix

Hi Pieter,

Would it be possible to include the current user location when using "zoomtofit"

So that not only the annotations are in the map, but also the current location ?

If possible with an option to include or exclude the current location with "zoomtofit".

Cheers,

Paul

We will add this on our feature request list.


Kind Regards, 
Pieter