2020-01-03-howto地理文件gpx文件修改

howto地理文件gpx文件修改

基于KissXML对gpx文件进行修改

参考:

https://www.jianshu.com/p/4f7390cf710f
https://github.com/robbiehanson/KissXML
GPX(GPS eXchange Format,GPS交换格式)是一个XML格式,为应用软件设计的通用GPS数据格式,专门用来存储地理信息。
一个GPX文件当中可能包含一些路点(waypoint)及一些轨迹点(trackpoint)。 以全球定位系统(GPS设备)所产生的GPX档为例, 路点可能是各自独立互不相干的重要标记点, 例如照相的地点或用户手动标记的休息站或路口等等;
至于GPS设备自动定时记录的则是轨迹点。 有顺序的一串轨迹点构成一个轨迹(track)或者路程(route)。轨迹是一个人曾经走过的记录,可能包含走错的路等等;路程则经常是建议未来用路人可以走的路径。
所以,一般来讲,轨迹里的点,包含时间信息,路程里的点,则没有时间信息。

代码:

usage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
打包 KissXML.framework 并加入工程
#import <KissXML/KissXML.h>
#import "YTRoutePoint.h"
主要代码
route_app_id是gpx文件的文件名
NSArray *a1rr = [self readGPXFileToPoints:[NSString stringWithFormat:@"%@/IDmoniLocation.gpx", NSHomeDirectory()] route_app_id:@"IDmoniLocation"];
NSMutableArray *a2rr = [NSMutableArray new];
NSLog(@"%@", a1rr);
for (YTRoutePoint *po1nt in a1rr) {
YTRoutePoint *po2nt = [YTRoutePoint new];
po2nt.lon = 1 + po1nt.lon;
po2nt.lat = 1 + po1nt.lat;
[a2rr addObject:po2nt];
}
[self writeXmlDocumentCallbackPath:@"IDmoniLocation" with:a2rr];
read write API函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
- (NSArray *)readGPXFileToPoints:(NSString *)filePath route_app_id:(NSString *)route_app_id
{
//转成XML字符串
NSString *xmlString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
DDXMLDocument *xmlDoc = [[DDXMLDocument alloc]initWithXMLString:xmlString options:0 error:nil];
//开始解析
NSArray *children = [xmlDoc nodesForXPath:@"gpx/wpt" error:nil];
NSMutableArray *points = [NSMutableArray arrayWithCapacity:children.count];
//遍历每个元素
YTRoutePoint *prevPoint = nil;
for (DDXMLElement *child in children) {
@autoreleasepool {
NSString *lat =[[child attributeForName:@"lat"] stringValue];
NSString *lon =[[child attributeForName:@"lon"] stringValue];
DDXMLElement *speedEle = [child elementForName:@"speed"];
DDXMLElement *timeEle = [child elementForName:@"time"];
DDXMLElement *distacneEle = [child elementForName:@"distacne"];
DDXMLElement *levelEle = [child elementForName:@"level"];
DDXMLElement *slopeEle = [child elementForName:@"slope"];
YTRoutePoint *point = [[YTRoutePoint alloc]init];
point.route_app_id = route_app_id;
point.lon = [lon doubleValue];
point.lat = [lat doubleValue];
point.speed = [[speedEle stringValue] doubleValue];
point.altude = [[levelEle stringValue] doubleValue];
point.distance = [[distacneEle stringValue] doubleValue];
point.slope = [[slopeEle stringValue] doubleValue];
point.create_time = [[timeEle stringValue] integerValue];
//去重
if(!prevPoint) {
[points addObject:point];
prevPoint = point;
}
else {
if(prevPoint.lat == point.lat && prevPoint.lon == point.lon) {
continue;
}
[points addObject:point];
prevPoint = point;
}
}
}
return [NSArray arrayWithArray:points];
}
- (NSString *)writeXmlDocumentCallbackPath:(NSString *)route_app_id with:(NSArray *)trackRoute
{
//gpx(root根)
DDXMLElement *gpxElement = [[DDXMLElement alloc]initWithName:@"gpx"];
// DDXMLNode *gpxUserID = [DDXMLNode attributeWithName:@"userid" stringValue:[[DataManagerObject shareDataManagerObject] getWildtoID]];
// [gpxElement addAttribute:gpxUserID];
// DDXMLNode *gpxUserName = [DDXMLNode attributeWithName:@"nickname" stringValue:[[DataManagerObject shareDataManagerObject] getUserNickName]];
// [gpxElement addAttribute:gpxUserName];
// DDXMLNode *gpxDevice = [DDXMLNode attributeWithName:@"device" stringValue:[UIDevice machineModelName]];
// [gpxElement addAttribute:gpxDevice];
// DDXMLNode *gpxVersion = [DDXMLNode attributeWithName:@"appversion" stringValue:YTAPPVersion];
// [gpxElement addAttribute:gpxVersion];
// DDXMLNode *gpxChannel = [DDXMLNode attributeWithName:@"channel" stringValue:@"wildto"];
// [gpxElement addAttribute:gpxChannel];
// DDXMLNode *gpxClient = [DDXMLNode attributeWithName:@"client" stringValue:YT_IOS_DEVICE];
// [gpxElement addAttribute:gpxClient];
NSArray *points = trackRoute;
for (NSInteger i = 0; i < points.count; i ++) {
@autoreleasepool {
YTRoutePoint *point = points[i];
//wpt元素(包含经纬度两个属性)
DDXMLElement *wptElement = [[DDXMLElement alloc]initWithName:@"wpt"];
DDXMLNode *wptLonAtt = [DDXMLNode attributeWithName:@"lon" stringValue:[NSString stringWithFormat:@"%f",point.lon]];
[wptElement addAttribute:wptLonAtt];
DDXMLNode *wptLatAtt = [DDXMLNode attributeWithName:@"lat" stringValue:[NSString stringWithFormat:@"%f",point.lat]];
[wptElement addAttribute:wptLatAtt];
//速度
DDXMLElement *speedElement = [[DDXMLElement alloc]initWithName:@"speed" stringValue:[NSString stringWithFormat:@"%f",point.speed]];
[wptElement addChild:speedElement];
//海拔
DDXMLElement *altudeElement = [[DDXMLElement alloc]initWithName:@"level" stringValue:[NSString stringWithFormat:@"%f",point.altude]];
[wptElement addChild:altudeElement];
//时间点(时间戳)
DDXMLElement *creatTimeElement = [[DDXMLElement alloc]initWithName:@"time" stringValue:[NSString stringWithFormat:@"%ld",(long)point.create_time]];
[wptElement addChild:creatTimeElement];
//坡度
DDXMLElement *slopeElement = [[DDXMLElement alloc]initWithName:@"slope" stringValue:[NSString stringWithFormat:@"%f",point.slope]];
[wptElement addChild:slopeElement];
//当前点经过的总距离
DDXMLElement *distacneElement = [[DDXMLElement alloc]initWithName:@"distacne" stringValue:[NSString stringWithFormat:@"%.1f",point.distance]];
[wptElement addChild:distacneElement];
[gpxElement addChild:wptElement];
}
}
NSString *xmlString = [@"<?xml version=\"1.0\"?>" stringByAppendingString:[gpxElement XMLString]];
NSLog(@"xmlString %@",xmlString);
DDXMLDocument *xmlDocument = [[DDXMLDocument alloc]initWithXMLString:xmlString options:0 error:nil];
NSString *path = [NSString stringWithFormat:@"%@/%@.gpx", NSHomeDirectory(), route_app_id];
NSLog(@"路劲 == %@",path);
NSString *result = [NSString stringWithFormat:@"%@",xmlDocument];
BOOL writed = [result writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:nil];
if (writed) {
return path;
}
return nil;
}
YTRoutePoint.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#import <Foundation/Foundation.h>
#import <CoreLocation/CLLocation.h>
#import <CoreLocation/CLPlacemark.h>
NS_ASSUME_NONNULL_BEGIN
@interface YTRoutePoint : NSObject
@property (nonatomic, strong) NSString *route_app_id;
@property (nonatomic, assign) double lon;
@property (nonatomic, assign) double lat;
@property (nonatomic, assign) double speed;
@property (nonatomic, assign) double altude;
@property (nonatomic, assign) double distance;
@property (nonatomic, assign) double slope;
@property (nonatomic, assign) NSInteger create_time;
@end
NS_ASSUME_NONNULL_END
YTRoutePoint.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#import "YTRoutePoint.h"
@implementation YTRoutePoint
- (instancetype)initWithDictionary:(NSDictionary *)dict {
if (self = [super init]) {
_route_app_id = [dict objectForKey:@"route_app_id"];
_lon = [[dict objectForKey:@"lon"] doubleValue];
_lat = [[dict objectForKey:@"lat"] doubleValue];
_speed = [[dict objectForKey:@"speed"] doubleValue];
_altude = [[dict objectForKey:@"altude"] doubleValue];
_distance = [[dict objectForKey:@"distance"] doubleValue];
_slope = [[dict objectForKey:@"slope"] doubleValue];
_create_time = [[dict objectForKey:@"create_time"] integerValue];
return self;
} else
return nil;
}
@end