在Xcode中使用GPX来模拟位置变化时,有没有办法控制速度?

lic*_*853 22 iphone xcode location gpx ios

我在Xcode 4.2中使用以下GPX文件来模拟位置更改.它运作良好,但我无法控制位置变化的速度.邮票似乎不起作用.有人有解决方案吗?

<?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>
Run Code Online (Sandbox Code Playgroud)

BB9*_*B9z 22

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>
Run Code Online (Sandbox Code Playgroud)

大约-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;
}
Run Code Online (Sandbox Code Playgroud)

  • @jmathew您可以使用正则表达式替换这些数字"\.\ d {3} Z"=>"Z" (3认同)
  • 当我尝试此操作时,Xcode 将读取该文件,但仍然指示速度为“-1.00 mps”。如果所有时间值都相同,则 Xcode 也会出现错误,它希望它们递增(尽管它们似乎没有发生任何事情...... (2认同)

Sta*_*nko 14

我不认为你可以用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);
}
Run Code Online (Sandbox Code Playgroud)

我创建了一步一步的演练,了解如何使用自动化和泄漏的位置模拟来抓取屏幕截图并找到泄漏点


Jia*_*Yow 11

我不认为(知道)直接在GPX中这是可能的,但您可以使用Instruments/Automation测试位置变化.

您将使用如下脚本:

var target = UIATarget.localTarget();
target.setLocation(<location);
target.delay(5);
target.setLocation(...);
Run Code Online (Sandbox Code Playgroud)

等等.我从WWDC11视频中获取了这个示例(测试您的位置感知应用程序)

我知道这实际上并没有让你定义速度,但延迟以某种方式解释了我希望的.也许那会对你有所帮助.


Sen*_*ful 9

如果您不想处理automator,可以使用GPX文件.诀窍是创建一堆点.

例如,不是仅创建从A到B的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;
}
Run Code Online (Sandbox Code Playgroud)

免责声明: kAppleTravelTime = 2只是猜测.如果您有更准确的价值,请在评论中发布.


Awa*_*yaz 6

更新:2018 年 10 月(Swift 4,Xcode 9.4)

我找到了一个非常简单的解决方案。虽然它不允许指定精确的速度,但是可以通过指定 gps 点之间的距离来控制速度。速度与两个 GPS 点之间的距离成正比。

  1. gpxGenerator.com生成 GPX 点
  2. 在 Xcode 中,从文件 -> 新建文件(或命令 N)创建一个新的 GPX。搜索 gpx
  3. 将您从 gpxGenerator.com 获得的 GPX 点粘贴到该 gpx 文件中
  4. 删除所有时间标签(这就是重点。不要忽略这一步)
  5. 运行您的应用程序并从调试菜单中选择您的 gpx 文件。(见屏幕截图)就我而言,它的名字是SanFranciscoToNewYork

就这样。现在,模拟器或真实设备应该使用 sp 模拟 gpx 文件中的点

从菜单中选择您的 gpx 文件


演示

在此处输入图片说明

正如您在演示中看到的,标记移动得非常快。这不是默认的慢速。一世

注意:是我用于演示的示例 GPX 文件

  • 此正则表达式可用于查找和替换所有时间戳 `&lt;time&gt;[0-9-T:Z]+&lt;/time&gt;` (2认同)