2012-03-21 25 views
8

Tôi đang viết một ứng dụng theo dõi vị trí của người dùng. Tôi có một đối tượng CLLocationManager sử dụng startMonitoringSignificantLocationChanges, vì vậy tôi có thể cập nhật vị trí từ nền khi ứng dụng không chạy. Tôi đã thiết lập ứng dụng của mình didFinishLaunchingWithOptions vì vậy nếu tôi nhận được khóa vị trí, tôi sẽ kích hoạt trình quản lý của mình để lấy vị trí của người dùng. Tất cả mọi thứ hoạt động tốt nhưng vấn đề là mỗi khi tôi nhận được một vị trí từ nền, Độ chính xác ngang của vị trí này là rất xấu. Trong hầu hết các trường hợp, nó là 1414 m.Location.HorizontalAccuracy quá xấu khi nhận vị trí từ nền

Có ai biết tại sao độ chính xác ngang quá xấu khi vị trí xuất phát từ nền không? Tôi có thể làm gì để có được vị trí chính xác hơn trong nền không?

Khi ứng dụng đang chạy tất cả các vị trí tôi nhận được rất chính xác, điều này chỉ xảy ra khi vị trí xuất phát từ nền. Điều đó có liên quan gì đến số lượng tháp di động tôi có trong thành phố của tôi không? Tôi đã suy nghĩ có lẽ các thiết bị không sử dụng gps của các nút wifi để có được vị trí trong nền.

Anyways, Mọi trợ giúp ở đây đều được đánh giá cao. Hãy chia sẻ suy nghĩ của bạn.

Cảm ơn!

+0

Nghiên cứu của người khác tại đây http://longweekendmobile.com/2010/07/22/iphone-background-gps-accurate-to-500-meters-not-enough-for-foot-traffic/ đề cập đến "CLLocationManager có xu hướng báo cáo nhiều sự kiện trong một khoảng thời gian rất ngắn, ngay cả trong nền (cách nhau chưa đến 10 giây) ... sự kiện thứ hai sẽ chính xác hơn nhiều so với lần đầu tiên " –

+0

Brian cảm ơn vì liên kết. Có một số thông tin rất hữu ích ở đó. Họ đã đề cập ở đó rằng một vị trí chính xác đến 500m khi nhận được từ nền, nhưng điều đó phụ thuộc vào thành phố của bạn. Tôi đã thử nghiệm ứng dụng của tôi ở đây tại Brasilia - Brazil và độ chính xác tốt nhất mà tôi đã đạt được là 1200m. –

Trả lời

11

Độ chính xác của các vị trí được trả về bởi CLLocationManager được xác định bởi desiredAccuracy, theo mặc định, kCLLocationAccuracyBest và theo độ chính xác có sẵn của thiết bị. Ví dụ: bạn có thể nhận được các vị trí kém chính xác hơn nếu pin của thiết bị yếu hoặc bạn có thể nhận được các vị trí chính xác hơn nếu chúng vẫn được lưu trong bộ nhớ cache từ một ứng dụng khác.

Tuy nhiên, việc bạn có được tọa độ cực kỳ chính xác sẽ tiêu hao một lượng điện đáng kể từ pin và sẽ rút thiết bị. Các ứng dụng trong nền có thể bị giới hạn ở độ phân giải thấp hơn nhiều về độ chính xác để cải thiện hiệu suất pin.

Vị trí chính xác yêu cầu nhiều nguồn để sử dụng đài GPS trong khi vị trí kém chính xác có thể dựa vào các điểm nóng wifi lân cận và tháp di động trong phạm vi điện thoại.

Khi ứng dụng của bạn tiếp tục từ nền, hệ thống sẽ cố gắng cải thiện độ chính xác của kết quả bạn nhận được. Đó là một khái niệm phức tạp, nhưng hãy xem ứng dụng Bản đồ trên điện thoại của bạn. Lúc đầu, vòng tròn đại diện cho vị trí của bạn là rất lớn; vì hệ thống có được cảm giác chính xác hơn về vị trí của bạn, vòng tròn trở nên nhỏ hơn. Hình ảnh này đại diện cho điện thoại sử dụng nhiều năng lượng hơn để có được vị trí chính xác hơn.

Bạn sẽ thấy hiện tượng tương tự với CLLocationManager khi ứng dụng của bạn tiếp tục từ nền: bạn sẽ nhận được vị trí không chính xác và nhận các bản cập nhật tiếp theo, chính xác hơn.

Đó là một sự thỏa hiệp giữa tiện lợi và thời lượng pin mà Apple phải thực hiện khi thiết kế API của họ. Bản cập nhật đầu tiên cho vị trí của người dùng có thể sẽ không chính xác trừ khi họ chỉ sử dụng ứng dụng Bản đồ và vị trí được lưu vào bộ nhớ cache.

Lời khuyên tốt nhất mà tôi có thể cung cấp cho bạn là lắng nghe các cập nhật tiếp theo từ người quản lý vị trí và cập nhật giao diện người dùng của bạn cho phù hợp. Chúc may mắn!

9

Như tên tiểu bang: Thông báo startMonitoringSignificantLocationChanges chỉ có ở đó để cho bạn biết rằng vị trí của người dùng khác biệt đáng kể so với lần cuối cùng được chọn. Đó là công việc của bạn khi bạn nhận được thông báo đó để cập nhật vị trí của bạn theo độ chính xác mong muốn mà bạn muốn. Thông báo sẽ không làm điều đó cho bạn.Nó sẽ chỉ cho bạn biết vị trí đã thay đổi để bạn có thể giải quyết tình huống tương ứng. Nếu bạn không biết làm thế nào để có được độ chính xác cao hơn, bạn có thể muốn kiểm tra mã mẫu của Apple cho LocateMe.Here một đoạn mã lưu trữ độ chính xác (bestEffortAtLocation) sau đó kiểm tra độ chính xác mỗi lần ủy nhiệm được gọi cho đến khi có kết quả tốt hơn hoặc một time-out xảy ra .:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { 
    // store all of the measurements, just so we can see what kind of data we might receive 
    [locationMeasurements addObject:newLocation]; 
    // test the age of the location measurement to determine if the measurement is cached 
    // in most cases you will not want to rely on cached measurements 
    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow]; 
    if (locationAge > 5.0) return; 
    // test that the horizontal accuracy does not indicate an invalid measurement 
    if (newLocation.horizontalAccuracy < 0) return; 
    // test the measurement to see if it is more accurate than the previous measurement 
    if (bestEffortAtLocation == nil || bestEffortAtLocation.horizontalAccuracy > newLocation.horizontalAccuracy) { 
     // store the location as the "best effort" 
     self.bestEffortAtLocation = newLocation; 
     // test the measurement to see if it meets the desired accuracy 
     // 
     // IMPORTANT!!! kCLLocationAccuracyBest should not be used for comparison with location coordinate or altitidue 
     // accuracy because it is a negative value. Instead, compare against some predetermined "real" measure of 
     // acceptable accuracy, or depend on the timeout to stop updating. This sample depends on the timeout. 
     // 
     if (newLocation.horizontalAccuracy <= locationManager.desiredAccuracy) { 
      // we have a measurement that meets our requirements, so we can stop updating the location 
      // 
      // IMPORTANT!!! Minimize power usage by stopping the location manager as soon as possible. 
      // 
      [self stopUpdatingLocation:NSLocalizedString(@"Acquired Location", @"Acquired Location")]; 
      // we can also cancel our previous performSelector:withObject:afterDelay: - it's no longer necessary 
      [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpdatingLocation:) object:nil]; 
     } 
    } 
    // update the display with the new location data 
} 

sự tín nhiệm cho Apple bởi vì đây là một đoạn thẳng từ mẫu mã LocateMe của họ:

http://developer.apple.com/library/ios/#samplecode/LocateMe/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007801-Intro-DontLinkElementID_2

vì vậy, khi bạn nhận được thông báo và nhu cầu để có được kết quả tốt hơn, bạn cần phải cập nhật tính chính xác và xem liệu điều đó có mang lại cho bạn một kết quả tốt hơn không t.

+0

Hubert, cảm ơn bạn đã trả lời. Đây thực sự là mã chính xác tôi đang sử dụng trong ứng dụng của mình và nó hoạt động tốt với ứng dụng đang chạy. Nhưng nó là nền tảng, tôi tiếp tục kiểm tra độ chính xác mỗi lần đại biểu được gọi, nhưng độ chính xác đó luôn luôn là xấu. Tôi nghĩ những gì Ash nói ở đây là đúng. Khi ứng dụng ở chế độ nền, điện thoại sẽ không sử dụng GPS để truy xuất vị trí để tiết kiệm pin và độ chính xác của vị trí chỉ nhận được từ tháp di động là xấu, ít nhất là trong thành phố của tôi. Có lẽ trong một thành phố có nhiều tháp di động, độ chính xác này có thể tốt hơn một chút. –

+0

Tôi rất vui vì bạn thấy lời khuyên của tôi hữu ích - bạn nên xem xét đánh dấu nó là câu trả lời được chấp nhận. –

Các vấn đề liên quan