Reputation: 6839
I draw path on MKMapView based on coordinates stored in SQLite on iPhone.
But now I stored 14000 coordinates (just lat/lng) in database and now when I want to display overlay path I get application crash.
My question is is there any way to optimize this code to be faster?
This is in view did load:
// ar is NSMutableArray and it is populate from database for a few seconds but code bellow cost me app crash
for(Path* p in ar)
{
self.routeLine = nil;
self.routeLineView = nil;
// while we create the route points, we will also be calculating the bounding box of our route
// so we can easily zoom in on it.
MKMapPoint northEastPoint;
MKMapPoint southWestPoint;
// create a c array of points.
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * ar.count);
for(int idx = 0; idx < ar.count; idx++)
{
Path *m_p = [ar objectAtIndex:idx];
CLLocationDegrees latitude = m_p.Latitude;
CLLocationDegrees longitude = m_p.Longitude;
// create our coordinate and add it to the correct spot in the array
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude);
MKMapPoint point = MKMapPointForCoordinate(coordinate);
// adjust the bounding box
// if it is the first point, just use them, since we have nothing to compare to yet.
if (idx == 0) {
northEastPoint = point;
southWestPoint = point;
}
else
{
if (point.x > northEastPoint.x)
northEastPoint.x = point.x;
if(point.y > northEastPoint.y)
northEastPoint.y = point.y;
if (point.x < southWestPoint.x)
southWestPoint.x = point.x;
if (point.y < southWestPoint.y)
southWestPoint.y = point.y;
}
pointArr[idx] = point;
}
// create the polyline based on the array of points.
self.routeLine = [MKPolyline polylineWithPoints:pointArr count:ar.count];
_routeRect = MKMapRectMake(southWestPoint.x, southWestPoint.y, northEastPoint.x - southWestPoint.x, northEastPoint.y - southWestPoint.y);
// clear the memory allocated earlier for the points
free(pointArr);
[self.mapView removeOverlays: self.mapView.overlays];
// add the overlay to the map
if (nil != self.routeLine) {
[self.mapView addOverlay:self.routeLine];
}
UPDATE
ViewDidLoad:
...
[self performSelectorInBackground:@selector(drawPathInBackground) withObject:nil];
...
-(void)drawPathInBackground{
for(int idx = 0; idx < ar.count; idx++)
{ ... }
[self.mapView performSelector:@selector(addOverlay:) onThread:[NSThread mainThread] withObject:self.routeLine waitUntilDone:YES];
}
I did like this and UI not freezes.
The only thing that left is how to draw MKPolyLine on every X points?
Upvotes: 1
Views: 2080
Reputation: 165
google has a algorithm that can encode the locations to string. for your situation , 14000 coordinates will be encoded to a String nearly 14000 length. then put the String into sqlite. it will accelerate the speed to get data from DB
Upvotes: 0
Reputation: 4618
Do fetching from the database and processing in a background thread.
Then reduce the number of coordinates in the path using the Douglas–Peucker algorithm:
And cache the results.
Upvotes: 4
Reputation: 425
If you have array of coordinates the use this code
here routes is array of coordinates.
NSLog(@"count %d",[routes count]);
MKMapPoint* pointArr = malloc(sizeof(CLLocationCoordinate2D) * [routes count]);
for(int idx = 0; idx < [routes count]; idx++)
{
CLLocation* location = [routes objectAtIndex:idx];
CLLocationCoordinate2D workingCoordinate;
workingCoordinate.latitude=location.coordinate.latitude;
workingCoordinate.longitude=location.coordinate.longitude;
NSLog(@"loop = %f,%f",workingCoordinate.latitude, workingCoordinate.longitude);
MKMapPoint point = MKMapPointForCoordinate(workingCoordinate);
pointArr[idx] = point;
}
// create the polyline based on the array of points.
self.routeLine = [MKPolyline polylineWithPoints:pointArr count:[routes count]];
[mapView addOverlay:self.routeLine];
free(pointArr);
Hope this helps.
Upvotes: 1
Reputation:
three approaches:
Upvotes: 4