Подтвердить что ты не робот

При использовании GPX в Xcode для имитации изменений местоположения существует ли способ контролировать скорость?

Я использую следующий файл 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>
4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

Поддержка 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;
}

Ответ 3

Я не думаю, что вы можете сделать это с 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, чтобы захватить скриншоты и найти утечки

Ответ 4

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

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

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

Инструкция:

  • Вставьте код ниже, настроив константу kDesiredSpeed ​​по своему вкусу.
  • Добавить UITapGestureRecognizer в ваше представление карты, связав его с mapViewTapped:
  • Добавить кнопки, которые вызывают startRecordingPoints и stopRecordingPoints.
  • Запустите приложение.
  • Нажмите кнопку startRecordingPoints.
  • Нажмите, где должен начинаться маршрут.
  • Нажмите другое местоположение на карте. Это создаст Х количество точек между последним node и новым node, чтобы оно показалось, что оно перемещается со скоростью, которую вы хотите.
  • Повторите предыдущий шаг столько раз, сколько хотите.
  • Нажмите кнопку остановки записи.
  • Скопируйте вывод консоли.
  • Файл > Новый файл...
  • Выберите "Ресурс" > "Файл GPX"
  • Вставьте содержимое и сохраните файл.
  • Нажмите стрелку местоположения в отладчике и выберите файл GPX.
  • Устройтесь поудобнее и смотрите, как местоположение обновляется с точно той скоростью, которую вы хотите!

Код:

@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 - это всего лишь предположение. Если у вас есть более точное значение, отправьте его в комментарии.

Ответ 5

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

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

(Подробнее см. AppleDoc)

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

Ответ 6

Обновление: октябрь 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


демонстрация

enter image description here

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

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

Ответ 7

Могу ли я покинуть свое место в пункте назначения на один час и затем вернуться обратно? Как будут отображаться значимые местоположения?