Fit map to objects in Carto mobile SDK

218 views Asked by At

I have an array of NTVectorElements, how do I set the map bounds so that it fits every element to the screen? I see the moveToFitBounds function but I’m not sure how to implement it. Do you have an example?

1

There are 1 answers

0
Nikitah On BEST ANSWER

I've dealt with this issue before. Figuring it out was not a trivial task, but I can provide an example snippet that solves this issue.

You need to provide screen bounds as well as map bounds, meaning the the minimum and maximum position required to draw a bounding box.

NTVectorElements there is no method to get object bounds immediately, you'd need to go through all of the elements in the array to find global max and min of their geometries

Here's a snippet to fit the map to currently loaded sites, you should only require few modifications to it to fit your use case:

-(void)fitMapToCurrentlyLoadedSites {
    int siteCount = (int)[_sitesOrderArray count];
    if (siteCount > 0) {
        if (siteCount == 1) {
            //zoom in on single site
            GenericMapMarker *siteMarker = [_sitesOrderArray objectAtIndex:0];
            NTMapPos *sitePosition = [CommonFunctions getMapPosFromCoordinate:_ntMapView coordinate:siteMarker.coordinate];
            [_ntMapView setFocusPos:sitePosition durationSeconds:0];
            [_ntMapView setZoom:15.0 durationSeconds:0];
        } else {
            //create vector of multiple sites
            NTMapPosVector* posVector = [[NTMapPosVector alloc] init];
            for (int i = 0; i < siteCount; i++) {
                GenericMapMarker *siteMarker = [_sitesOrderArray objectAtIndex:i];
                //get mapPos from coordinate
                NTMapPos *mapPos = [CommonFunctions getMapPosFromCoordinate:_ntMapView coordinate:siteMarker.coordinate];
                [posVector add:mapPos];
            }
            //create envelope of vectors
            NTMapEnvelope *envelope = [[NTMapEnvelope alloc] initWithConvexHull:posVector];
            //get mapBounds of envelope
            NTMapBounds *bounds = [envelope getBounds];

            [_ntMapView moveToFitBounds:bounds screenBounds:[self findScreenBounds] integerZoom:TRUE durationSeconds:1.0f];
        }
    }
}

And to find screen bounds:

-(NTScreenBounds *)findScreenBounds {
    float screenWidth = self.view.frame.size.width;
    float screenHeight = self.view.frame.size.height;
    NTScreenPos *minScreenPos = [[NTScreenPos alloc] initWithX:0.0 y:0.0];
    NTScreenPos *maxScreenPos = [[NTScreenPos alloc] initWithX:screenWidth y:screenHeight];
    return [[NTScreenBounds alloc] initWithMin:minScreenPos max:maxScreenPos];
}