Nic Hubbard
Nic Hubbard

Reputation: 42173

Adding random MKAnnotations around Current Location in a MKMapView

I have an MKMapView that shows the current users location. When I click a button in the navigation bar, I want to randomly drop 10 MKAnnotation pins. These can be dropped anywhere, randomly, but only within the current visible map area and around the current location.

How would go about doing something like this? Is there a way to have a long/lat range that is around the users location, but within the map area? Then, I could randomly choose from this range?

Basically, I need to find what coordinates are available in the current MKCoordinateRegion.

Is there a better way to go about this?

Upvotes: 3

Views: 2970

Answers (4)

Hashem Aboonajmi
Hashem Aboonajmi

Reputation: 13890

swift 4:

// returned coordinates all restricted to the provided bound
// nwCoordinate: north West coordinate of the target bound
// seCoordinate: south east coordinate of the target bound

func createRandomLocation(nwCoordinate: CLLocationCoordinate2D, seCoordinate: CLLocationCoordinate2D) -> [CLLocationCoordinate2D]
{
   return (0 ... 30).enumerated().map { _ in
        let latitude = randomFloatBetween(nwCoordinate.latitude, andBig: seCoordinate.latitude)
        let longitude = randomFloatBetween(nwCoordinate.longitude, andBig: seCoordinate.longitude)
        return CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

private func randomFloatBetween(_ smallNumber: Double, andBig bigNumber: Double) -> Double {
    let diff: Double = bigNumber - smallNumber
    return ((Double(arc4random() % (UInt32(RAND_MAX) + 1)) / Double(RAND_MAX)) * diff) + smallNumber
}

Upvotes: 0

Niklas
Niklas

Reputation: 1331

In Swift 3.0

func addPins() {
    let nePoint = CGPoint(x: mapView.bounds.origin.x + mapView.bounds.size.width, y: mapView.bounds.origin.y)
    let sePoint = CGPoint(x: mapView.bounds.origin.x, y: mapView.bounds.origin.y + mapView.bounds.size.height)

    let neCoord = mapView.convert(nePoint, toCoordinateFrom: mapView)
    let seCoord = mapView.convert(sePoint, toCoordinateFrom: mapView)

    var y = 5
    while y > 0 {
        let latRange = randomBetweenNumbers(firstNum: Float(neCoord.latitude), secondNum: Float(seCoord.latitude))
        let longRange = randomBetweenNumbers(firstNum: Float(neCoord.longitude), secondNum: Float(seCoord.longitude))
        let location = CLLocationCoordinate2D(latitude: CLLocationDegrees(latRange), longitude: CLLocationDegrees(longRange))
        let pin = MKPointAnnotation()
        pin.coordinate = location
        pin.title = "Home"
        mapView.addAnnotation(pin)
        y -= 1
    }

}

func randomBetweenNumbers(firstNum: Float, secondNum: Float) -> Float{
    return Float(arc4random()) / Float(UINT32_MAX) * abs(firstNum - secondNum) + min(firstNum, secondNum)
}

Upvotes: 0

Hiren
Hiren

Reputation: 12780

You can get your annotations using the distance between user location and other location

check out below code

#define DISTANCE_RADIUS     10.0    // in KM
-(NSArray *)findNearMe:(NSArray *)lounges {
NSMutableArray *arNearme = [NSMutableArray array];

CLLocation *currentLocation;
for(NSDictionary *d in lounges) 
{

currentLocation = [[CLLocation alloc] initWithLatitude:29.33891 longitude:48.077202];

    CGFloat latitude=[[d valueForKey:@"latitude"] floatValue];
    CGFloat longitude=[[d valueForKey:@"longitude"] floatValue];
    CLLocation *newPinLocation=[[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
    double distanceValue=[currentLocation distanceFromLocation:newPinLocation]; 

    if(distanceValue/1000.0<=DISTANCE_RADIUS) {
        [arNearme addObject:d];
    }
}
return  arNearme;
}

It will returns you an array of range of 1 to 1000 km near user location. Used the annotations array and show your annotations in to map view with user location.

Upvotes: 4

Nic Hubbard
Nic Hubbard

Reputation: 42173

I figured it out, here is how I did it:

/**
 * Adds new pins to the map
 *
 * @version $Revision: 0.1
 */
+ (void)addPinsToMap:(MKMapView *)mapView amount:(int)howMany {

    //First we need to calculate the corners of the map so we get the points
    CGPoint nePoint = CGPointMake(mapView.bounds.origin.x + mapView.bounds.size.width, mapView.bounds.origin.y);
    CGPoint swPoint = CGPointMake((mapView.bounds.origin.x), (mapView.bounds.origin.y + mapView.bounds.size.height));

    //Then transform those point into lat,lng values
    CLLocationCoordinate2D neCoord = [mapView convertPoint:nePoint toCoordinateFromView:mapView];
    CLLocationCoordinate2D swCoord = [mapView convertPoint:swPoint toCoordinateFromView:mapView];

    // Loop
    for (int y = 0; y < howMany; y++) {
        double latRange = [MapUtility randomFloatBetween:neCoord.latitude andBig:swCoord.latitude];
        double longRange = [MapUtility randomFloatBetween:neCoord.longitude andBig:swCoord.longitude];

        // Add new waypoint to map
        CLLocationCoordinate2D location = CLLocationCoordinate2DMake(latRange, longRange);
        MPin *pin = [[MPin alloc] init];
        pin.coordinate = location;
        [mapView addAnnotation:pin];

    }//end

}//end


/**
 * Random numbers
 *
 * @version $Revision: 0.1
 */
+ (double)randomFloatBetween:(double)smallNumber andBig:(double)bigNumber {
    double diff = bigNumber - smallNumber;
    return (((double) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + smallNumber;
}//end

Upvotes: 2

Related Questions