Reputation: 42173
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
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
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
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
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