При использовании GPX в XCode для симуляции изменений местоположения, есть ли способ контролировать скорость? - PullRequest
21 голосов
/ 25 февраля 2012

Я использую следующий файл GPX в Xcode 4.2 для имитации изменения местоположения. Это работает хорошо, но я не могу контролировать скорость изменения местоположения. штамп, кажется, не работает. У кого-нибудь есть решение для этого?

<?xml version="1.0"?>
<gpx version="1.1" creator="Xcode"> 
    <wpt lat="37.331705" lon="-122.030237"></wpt>
    <wpt lat="37.331705" lon="-122.030337"></wpt>
    <wpt lat="37.331705" lon="-122.030437"></wpt>
    <wpt lat="37.331705" lon="-122.030537"></wpt>
</gpx>

Ответы [ 6 ]

21 голосов
/ 05 апреля 2016

Поддержка XCode имитирует изменение скорости с помощью файла GPX.

Укажите одну или несколько путевых точек, содержащих пару широта / долгота.Если вы предоставите одну путевую точку, Xcode будет имитировать это конкретное местоположение.Если вы указали несколько путевых точек, Xcode будет имитировать маршрут посещения каждой путевой точки.

При необходимости укажите элемент времени для каждой путевой точки.Xcode будет интерполировать движение со скоростью, основанной на времени, прошедшем между каждой путевой точкой.Если вы не укажете элемент времени, Xcode будет использовать фиксированную скорость.Путевые точки должны быть отсортированы по времени в порядке возрастания.

Напишите так:

<wpt lat="39.96104510" lon="116.4450860">
    <time>2010-01-01T00:00:00Z</time>
</wpt>
<wpt lat="39.96090940" lon="116.4451400">
    <time>2010-01-01T00:00:05Z</time>
</wpt>
...
<wpt lat="39.96087240" lon="116.4450430">
    <time>2010-01-01T00:00:09Z</time>
</wpt>

О -1 скорость

CoreLocationСкорость объекта всегда будет равна -1 во время симуляции.Возможный обходной путь - сохранить последнее местоположение и рассчитать скорость самостоятельно.Пример кода:

CLLocationSpeed speed = location.speed;
if (speed < 0) {
    // A negative value indicates an invalid speed. Try calculate manually.
    CLLocation *lastLocation = self.lastLocation;
    NSTimeInterval time = [location.timestamp timeIntervalSinceDate:lastLocation.timestamp];

    if (time <= 0) {
        // If there are several location manager work at the same time, an outdated cache location may returns and should be ignored.
        return;
    }

    CLLocationDistance distanceFromLast = [lastLocation distanceFromLocation:location];
    if (distanceFromLast < DISTANCE_THRESHOLD
        || time < DURATION_THRESHOLD) {
        // Optional, dont calculate if two location are too close. This may avoid gets unreasonable value.
        return;
    }
    speed = distanceFromLast/time;
    self.lastLocation = location;
}
14 голосов
/ 29 июля 2012

Я не думаю, что вы можете сделать это с файлами GPX. Но это легко с инструментом автоматизации в Intruments. Вот один из сценариев, которые я использую для тестирования приложений и сбора скриншотов:

var target = UIATarget.localTarget();

// speed is in meters/sec
var points = [
          {location:{latitude:48.8899,longitude:14.2}, options:{speed:8, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          {location:{latitude:48.8899,longitude:14.9}, options:{speed:11, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          {location:{latitude:48.8899,longitude:14.6}, options:{speed:12, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          {location:{latitude:48.8899,longitude:14.7}, options:{speed:13, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          {location:{latitude:49.2,longitude:14.10}, options:{speed:15, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          {location:{latitude:49.4,longitude:14.8}, options:{speed:15, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          {location:{latitude:48.8899,longitude:14.9}, options:{speed:9, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          {location:{latitude:48.8899,longitude:15.1}, options:{speed:8, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          {location:{latitude:48.8899,longitude:16.1}, options:{speed:3, altitude:200, horizontalAccuracy:10, verticalAccuracy:15}},
          ];

for (var i = 0; i < points.length; i++)
{
target.setLocationWithOptions(points[i].location,points[i].options);
target.captureScreenWithName(i+"_.png");
target.delay(1.0);
}

Я создал пошаговое руководство для того, как я использовал симуляцию местоположения с Automation and Leaks для захвата скриншотов и поиска утечек

11 голосов
/ 25 февраля 2012

Я не думаю (не знаю), что это возможно в GPX напрямую, но вы можете проверить изменение местоположения с помощью Инструментов / Автоматизации.

Вы бы использовали скрипт вроде:

var target = UIATarget.localTarget();
target.setLocation(<location);
target.delay(5);
target.setLocation(...);

И так далее. Я взял этот пример из видео WWDC11 (Тестирование ваших приложений с учетом местоположения)

Я знаю, что это на самом деле не позволяет вам определять скорость, но задержки как-то объясняют это, я надеюсь. Может быть, это поможет вам.

9 голосов
/ 17 апреля 2014

Если вы не хотите иметь дело с автоматом, вы можете заставить его работать только с файлом GPX.Хитрость заключается в том, чтобы создать кучу точек.

Например, вместо создания 2 точек для перехода от А к В, создайте связку промежуточных точек между ними.Это работает, потому что симулятору местоположения требуется постоянное время для перемещения из одной точки в другую, независимо от расстояния между двумя точками.

Вместо того, чтобы создавать группу точек вручную, вы можете использовать следующий код.

Инструкции:

  1. Вставьте приведенный ниже код, подстраивая константу kDesiredSpeed ​​по своему вкусу.
  2. Добавьте UITapGestureRecognizer в вид карты,связывание его с mapViewTapped:
  3. Добавление кнопок, которые вызывают startRecordingPoints и stopRecordingPoints.
  4. Запустите приложение.
  5. Нажмите кнопку startRecordingPoints.
  6. Нажмите, гдеМаршрут должен начаться.
  7. Нажмите на другое место на карте.Это создаст количество точек X между последним узлом и новым узлом, так что он будет двигаться с необходимой вам скоростью.
  8. Повторите предыдущий шаг столько раз, сколько вы хотите.
  9. Нажмите «Остановить запись».
  10. Скопируйте вывод консоли.
  11. Файл> Новый файл ...
  12. Выберите «Ресурс»> «Файл GPX»
  13. Вставьте содержимое исохраните файл.
  14. Коснитесь стрелки местоположения в отладчике и выберите файл GPX.
  15. Сядьте и наблюдайте, как местоположение обновляется именно с той скоростью, которую вы хотите!

Код:

@property (strong, nonatomic) CLLocation *lastRecordedPoint;
@property (strong, nonatomic) NSMutableString *recordingOutput;

...

- (IBAction)mapViewTapped:(UITapGestureRecognizer *)sender {
    if (sender.state != UIGestureRecognizerStateEnded || !self.recordingOutput) {
        return;
    }

    CLLocationCoordinate2D coord = [self.mapView convertPoint:[sender locationInView:self.mapView]
                                         toCoordinateFromView:self.mapView];
    [self recordPoint:coord];
}

- (void)recordPoint:(CLLocationCoordinate2D)newPoint {
    const CGFloat kAppleTravelTime = 2; // the default time it takes to travel from one point to another
    const CGFloat kDesiredSpeed = 6; // meters per sec
    const CGFloat kDesiredDistanceBetweenPoints = kDesiredSpeed * kAppleTravelTime;
    NSString * const kFormatString = @"    <wpt lat=\"%f\" lon=\"%f\"></wpt>\n";

    CLLocation *newLocation = [[CLLocation alloc] initWithLatitude:newPoint.latitude longitude:newPoint.longitude];
    NSInteger numberOfPoints = 1;
    if (self.lastRecordedPoint) {
        CLLocationDistance distance = [self.lastRecordedPoint distanceFromLocation:newLocation];
        numberOfPoints = MAX(round(distance / kDesiredDistanceBetweenPoints), 1);
        CGFloat deltaLatitude = newPoint.latitude - self.lastRecordedPoint.coordinate.latitude;
        CGFloat deltaLongitude = newPoint.longitude - self.lastRecordedPoint.coordinate.longitude;
        for (NSInteger i = 0; i < numberOfPoints; i++) {
            CLLocationDegrees latitude = self.lastRecordedPoint.coordinate.latitude + (numberOfPoints/distance * deltaLatitude) * (i+1);
            CLLocationDegrees longitude = self.lastRecordedPoint.coordinate.longitude + (numberOfPoints/distance * deltaLongitude) * (i+1);
            [self.recordingOutput appendFormat:kFormatString, latitude, longitude];
        }
    } else {
        [self.recordingOutput appendFormat:kFormatString, newPoint.latitude, newPoint.longitude];
    }
    NSLog(@"Recorded %ld point(s) to: %f,%f", (long)numberOfPoints, newPoint.latitude, newPoint.longitude);

    self.lastRecordedPoint = newLocation;
}


- (void)startRecordingPoints {
    NSLog(@"Started recording points. Tap anywhere on the map to begin recording points.");
    self.recordingOutput = [NSMutableString string];
    [self.recordingOutput appendString:@"<?xml version=\"1.0\"?>\n<gpx version=\"1.1\" creator=\"Xcode\">\n"];
    self.lastRecordedPoint = nil;
}

- (void)stopRecordingPoints {
    [self.recordingOutput appendString:@"</gpx>"];
    NSLog(@"Done recording, here is your gpx file: \n%@", self.recordingOutput);
    self.recordingOutput = nil;
}

Отказ от ответственности: kAppleTravelTime = 2 - это только предположение.Если у вас есть более точное значение, пожалуйста, оставьте его в комментарии.

2 голосов
/ 30 марта 2012

Существует также метод, который позволяет передавать скорость и некоторые другие свойства:

target.setLocationWithOptions({latitude: 46.546928, longitude: 11.867127}, {altitude: 200.0, speed: 5});

(проверьте это AppleDoc для более подробной информации)

Вы все еще можете видеть свой NSLog в консольном приложении (/Applications/Utilities/Console.app). Просто добавьте фильтр, чтобы получить правильные результаты.

1 голос
/ 11 октября 2018

Обновление: октябрь 2018 г. (Swift 4, Xcode 9.4)

Я нашел очень простое решение.хотя это не позволяет указать точную скорость, однако скорость может контролироваться путем указания расстояния между точками GPS.Скорость прямо пропорциональна расстоянию между двумя точками GPS.

  1. Создание точек GPX из gpxGenerator.com
  2. В Xcode создайте новый GPX из файла -> Новый файл (или команда N).Поиск gpx
  3. Вставьте очки GPX, полученные с gpxGenerator.com, в этот файл gpx
  4. Удалите все теги времени (в этом суть. Не игнорируйте этошаг)
  5. Запустите ваше приложение и выберите файл gpx в меню отладки.(см. снимок экрана) В моем случае это имя SanFranciscoToNewYork

Вот и все.Теперь симулятор или реальное устройство должны симулировать точки в вашем файле gpx с помощью sp

Select your gpx file from menu


Demo

enter image description here

Как видно из демонстрации, маркер движется очень быстро.Это не медленная скорость по умолчанию.I

Примечание: Это - мой пример файла GPX, который я использовал для демонстрации

...