1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2025-01-14 14:43:17 +08:00

adding GPX support

This commit is contained in:
Patrik J. Braun 2018-11-26 00:26:29 +01:00
parent f1619ad984
commit 1a37b832be
28 changed files with 3610 additions and 43 deletions

View File

@ -120,7 +120,7 @@ apt-get install build-essential libkrb5-dev gcc g++
* gesture support (swipe left, right, up)
* Client side caching (directories and search results)
* Rendering **photos** with GPS coordinates **on google map**
* .gpx file support - `future plan`
* .gpx file support
* **Two modes: SQL database and no-database mode**
* both modes supports
* user management

View File

@ -151,12 +151,11 @@ export class GalleryMWs {
return next();
}
public static loadMedia(req: Request, res: Response, next: NextFunction) {
if (!(req.params.mediaPath)) {
public static loadFile(req: Request, res: Response, next: NextFunction) {
if (!(req.params.filePath)) {
return next();
}
const fullMediaPath = path.join(ProjectPath.ImageFolder, req.params.mediaPath);
const fullMediaPath = path.join(ProjectPath.ImageFolder, req.params.filePath);
// check if thumbnail already exist
if (fs.existsSync(fullMediaPath) === false) {

View File

@ -17,6 +17,8 @@ import {Brackets, Connection} from 'typeorm';
import {MediaEntity} from './enitites/MediaEntity';
import {MediaDTO} from '../../../common/entities/MediaDTO';
import {VideoEntity} from './enitites/VideoEntity';
import {FileEntity} from './enitites/FileEntity';
import {FileDTO} from '../../../common/entities/FileDTO';
export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
@ -30,6 +32,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
})
.leftJoinAndSelect('directory.directories', 'directories')
.leftJoinAndSelect('directory.media', 'media')
.leftJoinAndSelect('directory.metaFile', 'metaFile')
.getOne();
}
@ -202,6 +205,7 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
// saving to db
const directoryRepository = connection.getRepository(DirectoryEntity);
const mediaRepository = connection.getRepository(MediaEntity);
const fileRepository = connection.getRepository(FileEntity);
let currentDir: DirectoryEntity = await directoryRepository.createQueryBuilder('directory')
@ -299,6 +303,34 @@ export class GalleryManager implements IGalleryManager, ISQLGalleryManager {
}
await this.saveMedia(connection, mediaToSave);
await mediaRepository.remove(indexedMedia);
// save files
const indexedMetaFiles = await fileRepository.createQueryBuilder('file')
.where('file.directory = :dir', {
dir: currentDir.id
}).getMany();
const metaFilesToSave = [];
for (let i = 0; i < scannedDirectory.metaFile.length; i++) {
let metaFile: FileDTO = null;
for (let j = 0; j < indexedMetaFiles.length; j++) {
if (indexedMetaFiles[j].name === scannedDirectory.metaFile[i].name) {
metaFile = indexedMetaFiles[j];
indexedMetaFiles.splice(j, 1);
break;
}
}
if (metaFile == null) { //not in DB yet
scannedDirectory.metaFile[i].directory = null;
metaFile = Utils.clone(scannedDirectory.metaFile[i]);
scannedDirectory.metaFile[i].directory = scannedDirectory;
metaFile.directory = currentDir;
metaFilesToSave.push(metaFile);
}
}
await fileRepository.save(metaFilesToSave);
// await fileRepository.remove(indexedMetaFiles);
}
protected async saveMedia(connection: Connection, mediaList: MediaDTO[]): Promise<MediaEntity[]> {

View File

@ -14,6 +14,7 @@ import {Logger} from '../../Logger';
import {MediaEntity} from './enitites/MediaEntity';
import {VideoEntity} from './enitites/VideoEntity';
import {DataStructureVersion} from '../../../common/DataStructureVersion';
import {FileEntity} from './enitites/FileEntity';
export class SQLConnection {
@ -32,6 +33,7 @@ export class SQLConnection {
options.name = 'main';
options.entities = [
UserEntity,
FileEntity,
MediaEntity,
PhotoEntity,
VideoEntity,
@ -57,6 +59,7 @@ export class SQLConnection {
options.name = 'test';
options.entities = [
UserEntity,
FileEntity,
MediaEntity,
PhotoEntity,
VideoEntity,

View File

@ -93,11 +93,12 @@ export class SearchManager implements ISearchManager {
async search(text: string, searchType: SearchTypes): Promise<SearchResultDTO> {
const connection = await SQLConnection.getConnection();
const result: SearchResultDTO = <SearchResultDTO>{
const result: SearchResultDTO = {
searchText: text,
searchType: searchType,
directories: [],
media: [],
metaFile: [],
resultOverflow: false
};
@ -157,11 +158,12 @@ export class SearchManager implements ISearchManager {
async instantSearch(text: string): Promise<SearchResultDTO> {
const connection = await SQLConnection.getConnection();
const result: SearchResultDTO = <SearchResultDTO>{
const result: SearchResultDTO = {
searchText: text,
// searchType:undefined, not adding this
directories: [],
media: [],
metaFile: [],
resultOverflow: false
};

View File

@ -1,6 +1,7 @@
import {Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn} from 'typeorm';
import {DirectoryDTO} from '../../../../common/entities/DirectoryDTO';
import {MediaEntity} from './MediaEntity';
import {FileEntity} from './FileEntity';
@Entity()
export class DirectoryEntity implements DirectoryDTO {
@ -37,4 +38,8 @@ export class DirectoryEntity implements DirectoryDTO {
@OneToMany(type => MediaEntity, media => media.directory)
public media: MediaEntity[];
@OneToMany(type => FileEntity, file => file.directory)
public metaFile: FileEntity[];
}

View File

@ -0,0 +1,17 @@
import {Column, Entity, ManyToOne, PrimaryGeneratedColumn} from 'typeorm';
import {DirectoryEntity} from './DirectoryEntity';
import {FileDTO} from '../../../../common/entities/FileDTO';
@Entity()
export class FileEntity implements FileDTO {
@PrimaryGeneratedColumn()
id: number;
@Column('text')
name: string;
@ManyToOne(type => DirectoryEntity, directory => directory.metaFile, {onDelete: 'CASCADE'})
directory: DirectoryEntity;
}

View File

@ -3,6 +3,7 @@ import {DirectoryEntity} from './DirectoryEntity';
import {MediaDimension, MediaDTO, MediaMetadata} from '../../../../common/entities/MediaDTO';
import {OrientationTypes} from 'ts-exif-parser';
import {CameraMetadataEntity, PositionMetaDataEntity} from './PhotoEntity';
import {FileEntity} from './FileEntity';
export class MediaDimensionEntity implements MediaDimension {
@ -49,7 +50,7 @@ export class MediaMetadataEntity implements MediaMetadata {
// TODO: fix inheritance once its working in typeorm
@Entity()
@TableInheritance({column: {type: 'varchar', name: 'type'}})
export abstract class MediaEntity implements MediaDTO {
export abstract class MediaEntity implements MediaDTO {
@PrimaryGeneratedColumn()
id: number;

View File

@ -11,6 +11,7 @@ import {Config} from '../../../common/config/private/Config';
import {VideoDTO, VideoMetadata} from '../../../common/entities/VideoDTO';
import {MediaDimension} from '../../../common/entities/MediaDTO';
import {FFmpegFactory} from '../FFmpegFactory';
import {FileDTO} from '../../../common/entities/FileDTO';
const LOG_TAG = '[DiskManagerTask]';
@ -45,6 +46,15 @@ export class DiskMangerWorker {
return extensions.indexOf(extension) !== -1;
}
private static isMetaFile(fullPath: string) {
const extensions = [
'.gpx'
];
const extension = path.extname(fullPath).toLowerCase();
return extensions.indexOf(extension) !== -1;
}
public static scanDirectory(relativeDirectoryName: string, maxPhotos: number = null, photosOnly: boolean = false): Promise<DirectoryDTO> {
return new Promise<DirectoryDTO>((resolve, reject) => {
const directoryName = path.basename(relativeDirectoryName);
@ -52,14 +62,17 @@ export class DiskMangerWorker {
const absoluteDirectoryName = path.join(ProjectPath.ImageFolder, relativeDirectoryName);
const stat = fs.statSync(path.join(ProjectPath.ImageFolder, relativeDirectoryName));
const directory = <DirectoryDTO>{
const directory: DirectoryDTO = {
id: null,
parent: null,
name: directoryName,
path: directoryParent,
lastModified: Math.max(stat.ctime.getTime(), stat.mtime.getTime()),
lastScanned: Date.now(),
directories: [],
isPartial: false,
media: []
media: [],
metaFile: []
};
fs.readdir(absoluteDirectoryName, async (err, list: string[]) => {
if (err) {
@ -95,9 +108,12 @@ export class DiskMangerWorker {
metadata: await DiskMangerWorker.loadVideoMetadata(fullFilePath)
});
if (maxPhotos != null && directory.media.length > maxPhotos) {
break;
}
} else if (DiskMangerWorker.isMetaFile(fullFilePath)) {
directory.metaFile.push(<FileDTO>{
name: file,
directory: null,
});
}
}

View File

@ -13,6 +13,7 @@ export class GalleryRouter {
this.addGetVideoThumbnail(app);
this.addGetImage(app);
this.addGetVideo(app);
this.addGetMetaFile(app);
this.addRandom(app);
this.addDirectoryList(app);
@ -34,19 +35,28 @@ export class GalleryRouter {
private static addGetImage(app) {
app.get(['/api/gallery/content/:mediaPath(*\.(jpg|bmp|png|gif|jpeg))'],
app.get(['/api/gallery/content/:filePath(*\.(jpg|bmp|png|gif|jpeg))'],
AuthenticationMWs.authenticate,
// TODO: authorize path
GalleryMWs.loadMedia,
GalleryMWs.loadFile,
RenderingMWs.renderFile
);
}
private static addGetVideo(app) {
app.get(['/api/gallery/content/:mediaPath(*\.(mp4|ogg|ogv|webm))'],
app.get(['/api/gallery/content/:filePath(*\.(mp4|ogg|ogv|webm))'],
AuthenticationMWs.authenticate,
// TODO: authorize path
GalleryMWs.loadMedia,
GalleryMWs.loadFile,
RenderingMWs.renderFile
);
}
private static addGetMetaFile(app) {
app.get(['/api/gallery/content/:filePath(*\.(gpx))'],
AuthenticationMWs.authenticate,
// TODO: authorize path
GalleryMWs.loadFile,
RenderingMWs.renderFile
);
}
@ -57,36 +67,36 @@ export class GalleryRouter {
AuthenticationMWs.authorise(UserRoles.Guest),
// TODO: authorize path
GalleryMWs.getRandomImage,
GalleryMWs.loadMedia,
GalleryMWs.loadFile,
RenderingMWs.renderFile
);
}
private static addGetImageThumbnail(app) {
app.get('/api/gallery/content/:mediaPath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?',
app.get('/api/gallery/content/:filePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?',
AuthenticationMWs.authenticate,
// TODO: authorize path
GalleryMWs.loadMedia,
GalleryMWs.loadFile,
ThumbnailGeneratorMWs.generateThumbnailFactory(ThumbnailSourceType.Image),
RenderingMWs.renderFile
);
}
private static addGetVideoThumbnail(app) {
app.get('/api/gallery/content/:mediaPath(*\.(mp4|ogg|ogv|webm))/thumbnail/:size?',
app.get('/api/gallery/content/:filePath(*\.(mp4|ogg|ogv|webm))/thumbnail/:size?',
AuthenticationMWs.authenticate,
// TODO: authorize path
GalleryMWs.loadMedia,
GalleryMWs.loadFile,
ThumbnailGeneratorMWs.generateThumbnailFactory(ThumbnailSourceType.Video),
RenderingMWs.renderFile
);
}
private static addGetImageIcon(app) {
app.get('/api/gallery/content/:mediaPath(*\.(jpg|bmp|png|gif|jpeg))/icon',
app.get('/api/gallery/content/:filePath(*\.(jpg|bmp|png|gif|jpeg))/icon',
AuthenticationMWs.authenticate,
// TODO: authorize path
GalleryMWs.loadMedia,
GalleryMWs.loadFile,
ThumbnailGeneratorMWs.generateIconFactory(ThumbnailSourceType.Image),
RenderingMWs.renderFile
);

View File

@ -1 +1 @@
export const DataStructureVersion = 2;
export const DataStructureVersion = 3;

View File

@ -1,5 +1,6 @@
import {MediaDTO} from './MediaDTO';
import {PhotoDTO} from './PhotoDTO';
import {FileDTO} from './FileDTO';
export interface DirectoryDTO {
id: number;
@ -11,6 +12,7 @@ export interface DirectoryDTO {
parent: DirectoryDTO;
directories: Array<DirectoryDTO>;
media: MediaDTO[];
metaFile: FileDTO[];
}
export module DirectoryDTO {
@ -18,7 +20,9 @@ export module DirectoryDTO {
dir.media.forEach((media: MediaDTO) => {
media.directory = dir;
});
dir.metaFile.forEach((file: FileDTO) => {
file.directory = dir;
});
dir.directories.forEach((directory: DirectoryDTO) => {
addReferences(directory);
directory.parent = dir;
@ -29,7 +33,11 @@ export module DirectoryDTO {
dir.media.forEach((media: MediaDTO) => {
media.directory = null;
});
if (dir.metaFile) {
dir.metaFile.forEach((file: FileDTO) => {
file.directory = null;
});
}
if (dir.directories) {
dir.directories.forEach((directory: DirectoryDTO) => {
removeReferences(directory);

View File

@ -0,0 +1,11 @@
import {DirectoryDTO} from './DirectoryDTO';
import {PhotoDTO} from './PhotoDTO';
import {OrientationTypes} from 'ts-exif-parser';
import {VideoDTO} from './VideoDTO';
export interface FileDTO {
id: number;
name: string;
directory: DirectoryDTO;
}

View File

@ -2,8 +2,9 @@ import {DirectoryDTO} from './DirectoryDTO';
import {PhotoDTO} from './PhotoDTO';
import {OrientationTypes} from 'ts-exif-parser';
import {VideoDTO} from './VideoDTO';
import {FileDTO} from './FileDTO';
export interface MediaDTO {
export interface MediaDTO extends FileDTO{
id: number;
name: string;
directory: DirectoryDTO;

View File

@ -1,11 +1,13 @@
import {DirectoryDTO} from './DirectoryDTO';
import {PhotoDTO} from './PhotoDTO';
import {SearchTypes} from './AutoCompleteItem';
import {FileDTO} from './FileDTO';
export interface SearchResultDTO {
searchText: string;
searchType: SearchTypes;
directories: Array<DirectoryDTO>;
media: Array<PhotoDTO>;
searchType?: SearchTypes;
directories: DirectoryDTO[];
media: PhotoDTO[];
metaFile: FileDTO[];
resultOverflow: boolean;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,550 @@
<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.1"
creator="Runkeeper - http://www.runkeeper.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/1"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1">
<trk>
<name><![CDATA[Hiking 6/15/15 7:39 am]]></name>
<time>2015-06-15T14:39:55Z</time>
<trkseg>
<trkpt lat="40.466007000" lon="-121.514165000"><ele>2494.0</ele><time>2015-06-15T14:39:55Z</time></trkpt>
<trkpt lat="40.466047000" lon="-121.514143000"><ele>2495.1</ele><time>2015-06-15T14:39:58Z</time></trkpt>
<trkpt lat="40.466055000" lon="-121.514036000"><ele>2496.0</ele><time>2015-06-15T14:40:08Z</time></trkpt>
<trkpt lat="40.466130000" lon="-121.513986000"><ele>2496.1</ele><time>2015-06-15T14:41:20Z</time></trkpt>
<trkpt lat="40.466184000" lon="-121.513904000"><ele>2496.2</ele><time>2015-06-15T14:41:30Z</time></trkpt>
<trkpt lat="40.466257000" lon="-121.513855000"><ele>2496.3</ele><time>2015-06-15T14:41:40Z</time></trkpt>
<trkpt lat="40.466326000" lon="-121.513780000"><ele>2496.5</ele><time>2015-06-15T14:41:49Z</time></trkpt>
<trkpt lat="40.466397000" lon="-121.513721000"><ele>2496.8</ele><time>2015-06-15T14:41:57Z</time></trkpt>
<trkpt lat="40.466462000" lon="-121.513654000"><ele>2497.1</ele><time>2015-06-15T14:42:05Z</time></trkpt>
<trkpt lat="40.466534000" lon="-121.513600000"><ele>2497.4</ele><time>2015-06-15T14:42:13Z</time></trkpt>
<trkpt lat="40.466603000" lon="-121.513543000"><ele>2497.6</ele><time>2015-06-15T14:42:22Z</time></trkpt>
<trkpt lat="40.466665000" lon="-121.513464000"><ele>2497.9</ele><time>2015-06-15T14:42:33Z</time></trkpt>
<trkpt lat="40.466727000" lon="-121.513393000"><ele>2497.5</ele><time>2015-06-15T14:42:51Z</time></trkpt>
<trkpt lat="40.466765000" lon="-121.513288000"><ele>2496.8</ele><time>2015-06-15T14:43:03Z</time></trkpt>
<trkpt lat="40.466789000" lon="-121.513185000"><ele>2496.6</ele><time>2015-06-15T14:43:11Z</time></trkpt>
<trkpt lat="40.466813000" lon="-121.513073000"><ele>2496.5</ele><time>2015-06-15T14:43:21Z</time></trkpt>
<trkpt lat="40.466838000" lon="-121.512970000"><ele>2496.3</ele><time>2015-06-15T14:43:28Z</time></trkpt>
<trkpt lat="40.466843000" lon="-121.512860000"><ele>2496.1</ele><time>2015-06-15T14:43:37Z</time></trkpt>
<trkpt lat="40.466820000" lon="-121.512756000"><ele>2495.9</ele><time>2015-06-15T14:43:47Z</time></trkpt>
<trkpt lat="40.466802000" lon="-121.512649000"><ele>2495.7</ele><time>2015-06-15T14:43:55Z</time></trkpt>
<trkpt lat="40.466723000" lon="-121.512610000"><ele>2495.5</ele><time>2015-06-15T14:44:06Z</time></trkpt>
<trkpt lat="40.466639000" lon="-121.512592000"><ele>2495.4</ele><time>2015-06-15T14:44:18Z</time></trkpt>
<trkpt lat="40.466558000" lon="-121.512531000"><ele>2495.2</ele><time>2015-06-15T14:44:29Z</time></trkpt>
<trkpt lat="40.466508000" lon="-121.512444000"><ele>2495.0</ele><time>2015-06-15T14:44:38Z</time></trkpt>
<trkpt lat="40.466534000" lon="-121.512334000"><ele>2495.0</ele><time>2015-06-15T14:44:47Z</time></trkpt>
<trkpt lat="40.466588000" lon="-121.512242000"><ele>2493.3</ele><time>2015-06-15T14:44:55Z</time></trkpt>
<trkpt lat="40.466614000" lon="-121.512139000"><ele>2491.8</ele><time>2015-06-15T14:45:04Z</time></trkpt>
<trkpt lat="40.466538000" lon="-121.512091000"><ele>2490.4</ele><time>2015-06-15T14:45:17Z</time></trkpt>
<trkpt lat="40.466449000" lon="-121.512094000"><ele>2488.9</ele><time>2015-06-15T14:45:29Z</time></trkpt>
<trkpt lat="40.466363000" lon="-121.512068000"><ele>2487.5</ele><time>2015-06-15T14:45:37Z</time></trkpt>
<trkpt lat="40.466284000" lon="-121.512015000"><ele>2486.0</ele><time>2015-06-15T14:45:46Z</time></trkpt>
<trkpt lat="40.466264000" lon="-121.511911000"><ele>2486.2</ele><time>2015-06-15T14:45:53Z</time></trkpt>
<trkpt lat="40.466253000" lon="-121.511798000"><ele>2486.4</ele><time>2015-06-15T14:46:02Z</time></trkpt>
<trkpt lat="40.466264000" lon="-121.511675000"><ele>2486.8</ele><time>2015-06-15T14:46:09Z</time></trkpt>
<trkpt lat="40.466272000" lon="-121.511565000"><ele>2487.3</ele><time>2015-06-15T14:46:17Z</time></trkpt>
<trkpt lat="40.466282000" lon="-121.511455000"><ele>2487.7</ele><time>2015-06-15T14:46:25Z</time></trkpt>
<trkpt lat="40.466291000" lon="-121.511341000"><ele>2489.9</ele><time>2015-06-15T14:46:34Z</time></trkpt>
<trkpt lat="40.466334000" lon="-121.511242000"><ele>2491.8</ele><time>2015-06-15T14:46:43Z</time></trkpt>
<trkpt lat="40.466395000" lon="-121.511159000"><ele>2493.7</ele><time>2015-06-15T14:46:51Z</time></trkpt>
<trkpt lat="40.466446000" lon="-121.511072000"><ele>2495.6</ele><time>2015-06-15T14:46:59Z</time></trkpt>
<trkpt lat="40.466472000" lon="-121.510970000"><ele>2497.5</ele><time>2015-06-15T14:47:11Z</time></trkpt>
<trkpt lat="40.466461000" lon="-121.510860000"><ele>2499.5</ele><time>2015-06-15T14:47:34Z</time></trkpt>
<trkpt lat="40.466515000" lon="-121.510776000"><ele>2499.6</ele><time>2015-06-15T14:47:46Z</time></trkpt>
<trkpt lat="40.466587000" lon="-121.510710000"><ele>2499.8</ele><time>2015-06-15T14:47:53Z</time></trkpt>
<trkpt lat="40.466663000" lon="-121.510651000"><ele>2499.7</ele><time>2015-06-15T14:48:04Z</time></trkpt>
<trkpt lat="40.466658000" lon="-121.510533000"><ele>2499.6</ele><time>2015-06-15T14:48:18Z</time></trkpt>
<trkpt lat="40.466616000" lon="-121.510439000"><ele>2499.5</ele><time>2015-06-15T14:48:25Z</time></trkpt>
<trkpt lat="40.466578000" lon="-121.510341000"><ele>2499.5</ele><time>2015-06-15T14:48:32Z</time></trkpt>
<trkpt lat="40.466550000" lon="-121.510225000"><ele>2499.4</ele><time>2015-06-15T14:48:45Z</time></trkpt>
<trkpt lat="40.466556000" lon="-121.510106000"><ele>2499.3</ele><time>2015-06-15T14:49:21Z</time></trkpt>
<trkpt lat="40.466541000" lon="-121.509989000"><ele>2499.0</ele><time>2015-06-15T14:49:29Z</time></trkpt>
<trkpt lat="40.466535000" lon="-121.509881000"><ele>2498.7</ele><time>2015-06-15T14:49:36Z</time></trkpt>
<trkpt lat="40.466537000" lon="-121.509774000"><ele>2498.5</ele><time>2015-06-15T14:49:43Z</time></trkpt>
<trkpt lat="40.466548000" lon="-121.509664000"><ele>2498.5</ele><time>2015-06-15T14:49:51Z</time></trkpt>
<trkpt lat="40.466544000" lon="-121.509550000"><ele>2498.5</ele><time>2015-06-15T14:50:07Z</time></trkpt>
<trkpt lat="40.466554000" lon="-121.509437000"><ele>2498.5</ele><time>2015-06-15T14:50:42Z</time></trkpt>
<trkpt lat="40.466579000" lon="-121.509334000"><ele>2498.5</ele><time>2015-06-15T14:50:53Z</time></trkpt>
<trkpt lat="40.466618000" lon="-121.509442000"><ele>2498.5</ele><time>2015-06-15T14:51:52Z</time></trkpt>
<trkpt lat="40.466625000" lon="-121.509559000"><ele>2498.5</ele><time>2015-06-15T14:52:18Z</time></trkpt>
<trkpt lat="40.466628000" lon="-121.509668000"><ele>2498.5</ele><time>2015-06-15T14:52:28Z</time></trkpt>
<trkpt lat="40.466618000" lon="-121.509777000"><ele>2498.5</ele><time>2015-06-15T14:52:38Z</time></trkpt>
<trkpt lat="40.466626000" lon="-121.509889000"><ele>2498.7</ele><time>2015-06-15T14:52:49Z</time></trkpt>
<trkpt lat="40.466622000" lon="-121.510005000"><ele>2499.0</ele><time>2015-06-15T14:53:00Z</time></trkpt>
<trkpt lat="40.466622000" lon="-121.510116000"><ele>2499.3</ele><time>2015-06-15T14:53:11Z</time></trkpt>
<trkpt lat="40.466643000" lon="-121.510221000"><ele>2499.4</ele><time>2015-06-15T14:53:20Z</time></trkpt>
<trkpt lat="40.466660000" lon="-121.510327000"><ele>2499.5</ele><time>2015-06-15T14:53:29Z</time></trkpt>
<trkpt lat="40.466717000" lon="-121.510408000"><ele>2499.5</ele><time>2015-06-15T14:53:49Z</time></trkpt>
<trkpt lat="40.466791000" lon="-121.510460000"><ele>2499.6</ele><time>2015-06-15T14:54:09Z</time></trkpt>
<trkpt lat="40.466868000" lon="-121.510498000"><ele>2499.7</ele><time>2015-06-15T14:54:22Z</time></trkpt>
<trkpt lat="40.466798000" lon="-121.510435000"><ele>2499.8</ele><time>2015-06-15T14:56:22Z</time></trkpt>
<trkpt lat="40.466821000" lon="-121.510576000"><ele>2499.9</ele><time>2015-06-15T15:01:47Z</time></trkpt>
<trkpt lat="40.466737000" lon="-121.510611000"><ele>2500.0</ele><time>2015-06-15T15:02:03Z</time></trkpt>
<trkpt lat="40.466671000" lon="-121.510680000"><ele>2500.0</ele><time>2015-06-15T15:02:16Z</time></trkpt>
<trkpt lat="40.466573000" lon="-121.510717000"><ele>2499.8</ele><time>2015-06-15T15:02:32Z</time></trkpt>
<trkpt lat="40.466513000" lon="-121.510791000"><ele>2499.6</ele><time>2015-06-15T15:02:45Z</time></trkpt>
<trkpt lat="40.466440000" lon="-121.510842000"><ele>2499.5</ele><time>2015-06-15T15:02:57Z</time></trkpt>
<trkpt lat="40.466358000" lon="-121.510846000"><ele>2499.3</ele><time>2015-06-15T15:03:07Z</time></trkpt>
<trkpt lat="40.466295000" lon="-121.510765000"><ele>2499.1</ele><time>2015-06-15T15:03:59Z</time></trkpt>
<trkpt lat="40.466225000" lon="-121.510705000"><ele>2498.9</ele><time>2015-06-15T15:04:07Z</time></trkpt>
<trkpt lat="40.466137000" lon="-121.510686000"><ele>2498.7</ele><time>2015-06-15T15:04:16Z</time></trkpt>
<trkpt lat="40.466049000" lon="-121.510677000"><ele>2498.5</ele><time>2015-06-15T15:04:25Z</time></trkpt>
<trkpt lat="40.465966000" lon="-121.510687000"><ele>2498.4</ele><time>2015-06-15T15:04:34Z</time></trkpt>
<trkpt lat="40.465881000" lon="-121.510661000"><ele>2497.1</ele><time>2015-06-15T15:04:45Z</time></trkpt>
<trkpt lat="40.465791000" lon="-121.510670000"><ele>2495.8</ele><time>2015-06-15T15:04:56Z</time></trkpt>
<trkpt lat="40.465709000" lon="-121.510674000"><ele>2494.7</ele><time>2015-06-15T15:05:05Z</time></trkpt>
<trkpt lat="40.465623000" lon="-121.510650000"><ele>2493.6</ele><time>2015-06-15T15:05:15Z</time></trkpt>
<trkpt lat="40.465538000" lon="-121.510600000"><ele>2496.3</ele><time>2015-06-15T15:05:22Z</time></trkpt>
<trkpt lat="40.465466000" lon="-121.510537000"><ele>2498.9</ele><time>2015-06-15T15:05:30Z</time></trkpt>
<trkpt lat="40.465386000" lon="-121.510482000"><ele>2501.5</ele><time>2015-06-15T15:05:41Z</time></trkpt>
<trkpt lat="40.465311000" lon="-121.510426000"><ele>2504.2</ele><time>2015-06-15T15:05:52Z</time></trkpt>
<trkpt lat="40.465224000" lon="-121.510376000"><ele>2506.8</ele><time>2015-06-15T15:05:59Z</time></trkpt>
<trkpt lat="40.465142000" lon="-121.510327000"><ele>2509.5</ele><time>2015-06-15T15:06:06Z</time></trkpt>
<trkpt lat="40.465068000" lon="-121.510281000"><ele>2512.1</ele><time>2015-06-15T15:06:13Z</time></trkpt>
<trkpt lat="40.464985000" lon="-121.510253000"><ele>2515.2</ele><time>2015-06-15T15:06:21Z</time></trkpt>
<trkpt lat="40.464911000" lon="-121.510198000"><ele>2518.3</ele><time>2015-06-15T15:06:30Z</time></trkpt>
<trkpt lat="40.464824000" lon="-121.510203000"><ele>2521.4</ele><time>2015-06-15T15:06:42Z</time></trkpt>
<trkpt lat="40.464756000" lon="-121.510132000"><ele>2524.5</ele><time>2015-06-15T15:06:51Z</time></trkpt>
<trkpt lat="40.464677000" lon="-121.510101000"><ele>2523.8</ele><time>2015-06-15T15:06:59Z</time></trkpt>
<trkpt lat="40.464589000" lon="-121.510088000"><ele>2523.2</ele><time>2015-06-15T15:07:07Z</time></trkpt>
<trkpt lat="40.464507000" lon="-121.510085000"><ele>2522.5</ele><time>2015-06-15T15:07:19Z</time></trkpt>
<trkpt lat="40.464425000" lon="-121.510083000"><ele>2521.9</ele><time>2015-06-15T15:07:27Z</time></trkpt>
<trkpt lat="40.464336000" lon="-121.510092000"><ele>2521.3</ele><time>2015-06-15T15:07:35Z</time></trkpt>
<trkpt lat="40.464252000" lon="-121.510068000"><ele>2520.6</ele><time>2015-06-15T15:07:43Z</time></trkpt>
<trkpt lat="40.464173000" lon="-121.510033000"><ele>2520.0</ele><time>2015-06-15T15:07:51Z</time></trkpt>
<trkpt lat="40.464088000" lon="-121.510003000"><ele>2518.8</ele><time>2015-06-15T15:08:03Z</time></trkpt>
<trkpt lat="40.464012000" lon="-121.509954000"><ele>2517.6</ele><time>2015-06-15T15:08:10Z</time></trkpt>
<trkpt lat="40.463935000" lon="-121.509921000"><ele>2516.5</ele><time>2015-06-15T15:08:18Z</time></trkpt>
<trkpt lat="40.463865000" lon="-121.509845000"><ele>2515.3</ele><time>2015-06-15T15:08:27Z</time></trkpt>
<trkpt lat="40.463806000" lon="-121.509768000"><ele>2516.2</ele><time>2015-06-15T15:08:37Z</time></trkpt>
<trkpt lat="40.463724000" lon="-121.509719000"><ele>2517.1</ele><time>2015-06-15T15:08:46Z</time></trkpt>
<trkpt lat="40.463639000" lon="-121.509700000"><ele>2518.0</ele><time>2015-06-15T15:08:54Z</time></trkpt>
<trkpt lat="40.463556000" lon="-121.509665000"><ele>2518.9</ele><time>2015-06-15T15:09:03Z</time></trkpt>
<trkpt lat="40.463506000" lon="-121.509579000"><ele>2519.8</ele><time>2015-06-15T15:09:13Z</time></trkpt>
<trkpt lat="40.463516000" lon="-121.509470000"><ele>2520.7</ele><time>2015-06-15T15:09:24Z</time></trkpt>
<trkpt lat="40.463547000" lon="-121.509362000"><ele>2521.6</ele><time>2015-06-15T15:09:49Z</time></trkpt>
<trkpt lat="40.463526000" lon="-121.509248000"><ele>2523.7</ele><time>2015-06-15T15:09:58Z</time></trkpt>
<trkpt lat="40.463470000" lon="-121.509170000"><ele>2525.8</ele><time>2015-06-15T15:10:05Z</time></trkpt>
<trkpt lat="40.463394000" lon="-121.509131000"><ele>2527.9</ele><time>2015-06-15T15:10:10Z</time></trkpt>
<trkpt lat="40.463320000" lon="-121.509079000"><ele>2529.8</ele><time>2015-06-15T15:10:16Z</time></trkpt>
<trkpt lat="40.463246000" lon="-121.509023000"><ele>2529.6</ele><time>2015-06-15T15:10:22Z</time></trkpt>
<trkpt lat="40.463169000" lon="-121.508967000"><ele>2529.5</ele><time>2015-06-15T15:10:28Z</time></trkpt>
<trkpt lat="40.463086000" lon="-121.508927000"><ele>2529.3</ele><time>2015-06-15T15:10:34Z</time></trkpt>
<trkpt lat="40.462999000" lon="-121.508944000"><ele>2529.1</ele><time>2015-06-15T15:10:41Z</time></trkpt>
<trkpt lat="40.462910000" lon="-121.508952000"><ele>2528.9</ele><time>2015-06-15T15:10:51Z</time></trkpt>
<trkpt lat="40.462824000" lon="-121.508923000"><ele>2528.7</ele><time>2015-06-15T15:10:59Z</time></trkpt>
<trkpt lat="40.462743000" lon="-121.508925000"><ele>2528.5</ele><time>2015-06-15T15:11:06Z</time></trkpt>
<trkpt lat="40.462656000" lon="-121.508920000"><ele>2528.4</ele><time>2015-06-15T15:11:14Z</time></trkpt>
<trkpt lat="40.462580000" lon="-121.508959000"><ele>2528.2</ele><time>2015-06-15T15:11:23Z</time></trkpt>
<trkpt lat="40.462506000" lon="-121.509017000"><ele>2528.7</ele><time>2015-06-15T15:11:32Z</time></trkpt>
<trkpt lat="40.462429000" lon="-121.509055000"><ele>2529.5</ele><time>2015-06-15T15:11:43Z</time></trkpt>
<trkpt lat="40.462339000" lon="-121.509047000"><ele>2530.2</ele><time>2015-06-15T15:11:52Z</time></trkpt>
<trkpt lat="40.462259000" lon="-121.509028000"><ele>2530.9</ele><time>2015-06-15T15:12:00Z</time></trkpt>
<trkpt lat="40.462174000" lon="-121.509037000"><ele>2531.6</ele><time>2015-06-15T15:12:09Z</time></trkpt>
<trkpt lat="40.462085000" lon="-121.509058000"><ele>2532.4</ele><time>2015-06-15T15:12:18Z</time></trkpt>
<trkpt lat="40.462003000" lon="-121.509037000"><ele>2533.1</ele><time>2015-06-15T15:12:26Z</time></trkpt>
<trkpt lat="40.461920000" lon="-121.509028000"><ele>2533.8</ele><time>2015-06-15T15:12:36Z</time></trkpt>
<trkpt lat="40.461843000" lon="-121.509081000"><ele>2534.5</ele><time>2015-06-15T15:12:47Z</time></trkpt>
<trkpt lat="40.461761000" lon="-121.509131000"><ele>2535.3</ele><time>2015-06-15T15:12:55Z</time></trkpt>
<trkpt lat="40.461688000" lon="-121.509194000"><ele>2534.9</ele><time>2015-06-15T15:13:03Z</time></trkpt>
<trkpt lat="40.461621000" lon="-121.509269000"><ele>2533.8</ele><time>2015-06-15T15:13:12Z</time></trkpt>
<trkpt lat="40.461596000" lon="-121.509385000"><ele>2532.7</ele><time>2015-06-15T15:13:19Z</time></trkpt>
<trkpt lat="40.461547000" lon="-121.509477000"><ele>2531.6</ele><time>2015-06-15T15:13:26Z</time></trkpt>
<trkpt lat="40.461476000" lon="-121.509533000"><ele>2530.5</ele><time>2015-06-15T15:13:34Z</time></trkpt>
<trkpt lat="40.461393000" lon="-121.509577000"><ele>2529.5</ele><time>2015-06-15T15:13:42Z</time></trkpt>
<trkpt lat="40.461317000" lon="-121.509625000"><ele>2529.5</ele><time>2015-06-15T15:13:50Z</time></trkpt>
<trkpt lat="40.461232000" lon="-121.509634000"><ele>2529.6</ele><time>2015-06-15T15:14:00Z</time></trkpt>
<trkpt lat="40.461144000" lon="-121.509619000"><ele>2529.7</ele><time>2015-06-15T15:14:09Z</time></trkpt>
<trkpt lat="40.461060000" lon="-121.509632000"><ele>2529.8</ele><time>2015-06-15T15:14:27Z</time></trkpt>
<trkpt lat="40.460981000" lon="-121.509590000"><ele>2529.9</ele><time>2015-06-15T15:14:39Z</time></trkpt>
<trkpt lat="40.460934000" lon="-121.509504000"><ele>2531.1</ele><time>2015-06-15T15:14:47Z</time></trkpt>
<trkpt lat="40.460889000" lon="-121.509405000"><ele>2532.3</ele><time>2015-06-15T15:14:55Z</time></trkpt>
<trkpt lat="40.460865000" lon="-121.509302000"><ele>2533.5</ele><time>2015-06-15T15:15:04Z</time></trkpt>
<trkpt lat="40.460874000" lon="-121.509195000"><ele>2535.1</ele><time>2015-06-15T15:15:13Z</time></trkpt>
<trkpt lat="40.460873000" lon="-121.509086000"><ele>2536.7</ele><time>2015-06-15T15:15:22Z</time></trkpt>
<trkpt lat="40.460879000" lon="-121.508975000"><ele>2538.4</ele><time>2015-06-15T15:15:32Z</time></trkpt>
<trkpt lat="40.460909000" lon="-121.508871000"><ele>2538.8</ele><time>2015-06-15T15:15:45Z</time></trkpt>
<trkpt lat="40.460901000" lon="-121.508756000"><ele>2539.3</ele><time>2015-06-15T15:15:53Z</time></trkpt>
<trkpt lat="40.460864000" lon="-121.508661000"><ele>2539.7</ele><time>2015-06-15T15:16:00Z</time></trkpt>
<trkpt lat="40.460817000" lon="-121.508572000"><ele>2540.2</ele><time>2015-06-15T15:16:07Z</time></trkpt>
<trkpt lat="40.460743000" lon="-121.508506000"><ele>2540.6</ele><time>2015-06-15T15:16:16Z</time></trkpt>
<trkpt lat="40.460685000" lon="-121.508430000"><ele>2541.1</ele><time>2015-06-15T15:16:40Z</time></trkpt>
<trkpt lat="40.460644000" lon="-121.508325000"><ele>2541.5</ele><time>2015-06-15T15:16:48Z</time></trkpt>
<trkpt lat="40.460655000" lon="-121.508208000"><ele>2542.0</ele><time>2015-06-15T15:16:57Z</time></trkpt>
<trkpt lat="40.460653000" lon="-121.508098000"><ele>2542.0</ele><time>2015-06-15T15:17:16Z</time></trkpt>
<trkpt lat="40.460713000" lon="-121.508010000"><ele>2543.2</ele><time>2015-06-15T15:18:53Z</time></trkpt>
<trkpt lat="40.460794000" lon="-121.508009000"><ele>2543.2</ele><time>2015-06-15T15:20:06Z</time></trkpt>
<trkpt lat="40.460707000" lon="-121.507973000"><ele>2543.2</ele><time>2015-06-15T15:20:55Z</time></trkpt>
<trkpt lat="40.460623000" lon="-121.507957000"><ele>2543.2</ele><time>2015-06-15T15:21:12Z</time></trkpt>
<trkpt lat="40.460542000" lon="-121.507907000"><ele>2543.2</ele><time>2015-06-15T15:21:20Z</time></trkpt>
<trkpt lat="40.460487000" lon="-121.507820000"><ele>2543.2</ele><time>2015-06-15T15:21:29Z</time></trkpt>
<trkpt lat="40.460456000" lon="-121.507717000"><ele>2543.2</ele><time>2015-06-15T15:21:38Z</time></trkpt>
<trkpt lat="40.460428000" lon="-121.507616000"><ele>2543.2</ele><time>2015-06-15T15:21:47Z</time></trkpt>
<trkpt lat="40.460398000" lon="-121.507516000"><ele>2544.7</ele><time>2015-06-15T15:21:56Z</time></trkpt>
<trkpt lat="40.460368000" lon="-121.507416000"><ele>2546.3</ele><time>2015-06-15T15:22:06Z</time></trkpt>
<trkpt lat="40.460319000" lon="-121.507328000"><ele>2547.8</ele><time>2015-06-15T15:22:19Z</time></trkpt>
<trkpt lat="40.460262000" lon="-121.507251000"><ele>2548.2</ele><time>2015-06-15T15:22:29Z</time></trkpt>
<trkpt lat="40.460192000" lon="-121.507139000"><ele>2549.7</ele><time>2015-06-15T15:22:43Z</time></trkpt>
<trkpt lat="40.460136000" lon="-121.507058000"><ele>2551.3</ele><time>2015-06-15T15:22:50Z</time></trkpt>
<trkpt lat="40.460070000" lon="-121.506986000"><ele>2552.8</ele><time>2015-06-15T15:22:57Z</time></trkpt>
<trkpt lat="40.459998000" lon="-121.506917000"><ele>2554.4</ele><time>2015-06-15T15:23:04Z</time></trkpt>
<trkpt lat="40.459929000" lon="-121.506844000"><ele>2555.9</ele><time>2015-06-15T15:23:14Z</time></trkpt>
<trkpt lat="40.459860000" lon="-121.506765000"><ele>2555.7</ele><time>2015-06-15T15:23:22Z</time></trkpt>
<trkpt lat="40.459837000" lon="-121.506657000"><ele>2555.5</ele><time>2015-06-15T15:23:30Z</time></trkpt>
<trkpt lat="40.459791000" lon="-121.506565000"><ele>2553.8</ele><time>2015-06-15T15:23:38Z</time></trkpt>
<trkpt lat="40.459721000" lon="-121.506497000"><ele>2553.9</ele><time>2015-06-15T15:23:50Z</time></trkpt>
<trkpt lat="40.459658000" lon="-121.506414000"><ele>2554.0</ele><time>2015-06-15T15:23:59Z</time></trkpt>
<trkpt lat="40.459618000" lon="-121.506316000"><ele>2554.1</ele><time>2015-06-15T15:24:06Z</time></trkpt>
<trkpt lat="40.459575000" lon="-121.506216000"><ele>2554.2</ele><time>2015-06-15T15:24:15Z</time></trkpt>
<trkpt lat="40.459523000" lon="-121.506129000"><ele>2554.3</ele><time>2015-06-15T15:24:25Z</time></trkpt>
<trkpt lat="40.459467000" lon="-121.506047000"><ele>2554.4</ele><time>2015-06-15T15:24:34Z</time></trkpt>
<trkpt lat="40.459385000" lon="-121.505969000"><ele>2554.5</ele><time>2015-06-15T15:24:46Z</time></trkpt>
<trkpt lat="40.459315000" lon="-121.505899000"><ele>2554.5</ele><time>2015-06-15T15:24:54Z</time></trkpt>
<trkpt lat="40.459246000" lon="-121.505833000"><ele>2556.4</ele><time>2015-06-15T15:25:02Z</time></trkpt>
<trkpt lat="40.459182000" lon="-121.505766000"><ele>2558.2</ele><time>2015-06-15T15:25:08Z</time></trkpt>
<trkpt lat="40.459100000" lon="-121.505719000"><ele>2560.0</ele><time>2015-06-15T15:25:14Z</time></trkpt>
<trkpt lat="40.459020000" lon="-121.505691000"><ele>2559.3</ele><time>2015-06-15T15:25:21Z</time></trkpt>
<trkpt lat="40.458941000" lon="-121.505657000"><ele>2557.8</ele><time>2015-06-15T15:25:28Z</time></trkpt>
<trkpt lat="40.458842000" lon="-121.505602000"><ele>2556.4</ele><time>2015-06-15T15:25:42Z</time></trkpt>
<trkpt lat="40.458762000" lon="-121.505563000"><ele>2554.9</ele><time>2015-06-15T15:25:55Z</time></trkpt>
<trkpt lat="40.458773000" lon="-121.505448000"><ele>2553.5</ele><time>2015-06-15T15:26:06Z</time></trkpt>
<trkpt lat="40.458713000" lon="-121.505325000"><ele>2552.0</ele><time>2015-06-15T15:26:45Z</time></trkpt>
<trkpt lat="40.458651000" lon="-121.505250000"><ele>2550.5</ele><time>2015-06-15T15:26:56Z</time></trkpt>
<trkpt lat="40.458598000" lon="-121.505166000"><ele>2549.1</ele><time>2015-06-15T15:30:46Z</time></trkpt>
<trkpt lat="40.458508000" lon="-121.505213000"><ele>2547.6</ele><time>2015-06-15T15:31:42Z</time></trkpt>
<trkpt lat="40.458391000" lon="-121.505190000"><ele>2546.2</ele><time>2015-06-15T15:32:10Z</time></trkpt>
<trkpt lat="40.458305000" lon="-121.505177000"><ele>2545.2</ele><time>2015-06-15T15:32:24Z</time></trkpt>
<trkpt lat="40.458222000" lon="-121.505156000"><ele>2544.9</ele><time>2015-06-15T15:32:36Z</time></trkpt>
<trkpt lat="40.458139000" lon="-121.505116000"><ele>2545.4</ele><time>2015-06-15T15:32:48Z</time></trkpt>
<trkpt lat="40.458055000" lon="-121.505092000"><ele>2545.8</ele><time>2015-06-15T15:32:59Z</time></trkpt>
<trkpt lat="40.457976000" lon="-121.505063000"><ele>2546.3</ele><time>2015-06-15T15:33:11Z</time></trkpt>
<trkpt lat="40.457887000" lon="-121.505043000"><ele>2546.7</ele><time>2015-06-15T15:33:21Z</time></trkpt>
<trkpt lat="40.457818000" lon="-121.504988000"><ele>2547.2</ele><time>2015-06-15T15:33:33Z</time></trkpt>
<trkpt lat="40.457735000" lon="-121.504979000"><ele>2547.6</ele><time>2015-06-15T15:33:44Z</time></trkpt>
<trkpt lat="40.457648000" lon="-121.504979000"><ele>2548.1</ele><time>2015-06-15T15:33:53Z</time></trkpt>
<trkpt lat="40.457565000" lon="-121.504961000"><ele>2546.5</ele><time>2015-06-15T15:34:03Z</time></trkpt>
<trkpt lat="40.457489000" lon="-121.504908000"><ele>2545.0</ele><time>2015-06-15T15:34:14Z</time></trkpt>
<trkpt lat="40.457437000" lon="-121.504819000"><ele>2543.0</ele><time>2015-06-15T15:34:29Z</time></trkpt>
<trkpt lat="40.457419000" lon="-121.504702000"><ele>2541.0</ele><time>2015-06-15T15:34:37Z</time></trkpt>
<trkpt lat="40.457400000" lon="-121.504591000"><ele>2539.0</ele><time>2015-06-15T15:34:45Z</time></trkpt>
<trkpt lat="40.457388000" lon="-121.504477000"><ele>2537.0</ele><time>2015-06-15T15:34:54Z</time></trkpt>
<trkpt lat="40.457321000" lon="-121.504401000"><ele>2535.0</ele><time>2015-06-15T15:35:03Z</time></trkpt>
<trkpt lat="40.457284000" lon="-121.504299000"><ele>2533.0</ele><time>2015-06-15T15:35:13Z</time></trkpt>
<trkpt lat="40.457297000" lon="-121.504187000"><ele>2531.0</ele><time>2015-06-15T15:35:22Z</time></trkpt>
<trkpt lat="40.457382000" lon="-121.504211000"><ele>2529.0</ele><time>2015-06-15T15:35:33Z</time></trkpt>
<trkpt lat="40.457461000" lon="-121.504180000"><ele>2527.0</ele><time>2015-06-15T15:35:42Z</time></trkpt>
<trkpt lat="40.457519000" lon="-121.504102000"><ele>2525.2</ele><time>2015-06-15T15:35:55Z</time></trkpt>
<trkpt lat="40.457514000" lon="-121.503992000"><ele>2523.4</ele><time>2015-06-15T15:36:10Z</time></trkpt>
<trkpt lat="40.457481000" lon="-121.503890000"><ele>2521.5</ele><time>2015-06-15T15:36:24Z</time></trkpt>
<trkpt lat="40.457432000" lon="-121.503801000"><ele>2519.7</ele><time>2015-06-15T15:36:36Z</time></trkpt>
<trkpt lat="40.457363000" lon="-121.503739000"><ele>2517.9</ele><time>2015-06-15T15:36:46Z</time></trkpt>
<trkpt lat="40.457366000" lon="-121.503627000"><ele>2517.3</ele><time>2015-06-15T15:36:56Z</time></trkpt>
<trkpt lat="40.457340000" lon="-121.503526000"><ele>2516.6</ele><time>2015-06-15T15:37:05Z</time></trkpt>
<trkpt lat="40.457308000" lon="-121.503426000"><ele>2516.0</ele><time>2015-06-15T15:37:14Z</time></trkpt>
<trkpt lat="40.457248000" lon="-121.503326000"><ele>2515.4</ele><time>2015-06-15T15:37:27Z</time></trkpt>
<trkpt lat="40.457184000" lon="-121.503247000"><ele>2512.5</ele><time>2015-06-15T15:37:37Z</time></trkpt>
<trkpt lat="40.457110000" lon="-121.503179000"><ele>2511.9</ele><time>2015-06-15T15:37:51Z</time></trkpt>
<trkpt lat="40.457044000" lon="-121.503092000"><ele>2511.9</ele><time>2015-06-15T15:37:59Z</time></trkpt>
<trkpt lat="40.456987000" lon="-121.503011000"><ele>2511.9</ele><time>2015-06-15T15:38:07Z</time></trkpt>
<trkpt lat="40.456936000" lon="-121.502926000"><ele>2511.9</ele><time>2015-06-15T15:38:19Z</time></trkpt>
<trkpt lat="40.456983000" lon="-121.502834000"><ele>2511.9</ele><time>2015-06-15T15:38:41Z</time></trkpt>
<trkpt lat="40.457098000" lon="-121.502836000"><ele>2510.9</ele><time>2015-06-15T15:39:02Z</time></trkpt>
<trkpt lat="40.457168000" lon="-121.502891000"><ele>2509.7</ele><time>2015-06-15T15:39:46Z</time></trkpt>
<trkpt lat="40.457242000" lon="-121.502937000"><ele>2508.5</ele><time>2015-06-15T15:39:56Z</time></trkpt>
<trkpt lat="40.457329000" lon="-121.502956000"><ele>2507.4</ele><time>2015-06-15T15:40:06Z</time></trkpt>
<trkpt lat="40.457406000" lon="-121.502881000"><ele>2506.2</ele><time>2015-06-15T15:40:18Z</time></trkpt>
<trkpt lat="40.457434000" lon="-121.502777000"><ele>2506.2</ele><time>2015-06-15T15:41:36Z</time></trkpt>
<trkpt lat="40.457402000" lon="-121.502878000"><ele>2504.0</ele><time>2015-06-15T15:55:11Z</time></trkpt>
<trkpt lat="40.457337000" lon="-121.502946000"><ele>2503.0</ele><time>2015-06-15T15:55:27Z</time></trkpt>
<trkpt lat="40.457256000" lon="-121.502920000"><ele>2502.0</ele><time>2015-06-15T15:55:34Z</time></trkpt>
<trkpt lat="40.457182000" lon="-121.502872000"><ele>2501.0</ele><time>2015-06-15T15:55:42Z</time></trkpt>
<trkpt lat="40.457137000" lon="-121.502780000"><ele>2500.0</ele><time>2015-06-15T15:55:51Z</time></trkpt>
<trkpt lat="40.457120000" lon="-121.502668000"><ele>2500.0</ele><time>2015-06-15T15:55:59Z</time></trkpt>
<trkpt lat="40.457175000" lon="-121.502576000"><ele>2499.0</ele><time>2015-06-15T15:56:06Z</time></trkpt>
<trkpt lat="40.457256000" lon="-121.502517000"><ele>2498.0</ele><time>2015-06-15T15:56:15Z</time></trkpt>
<trkpt lat="40.457324000" lon="-121.502437000"><ele>2497.0</ele><time>2015-06-15T15:56:24Z</time></trkpt>
<trkpt lat="40.457350000" lon="-121.502300000"><ele>2496.0</ele><time>2015-06-15T15:57:21Z</time></trkpt>
<trkpt lat="40.457430000" lon="-121.502277000"><ele>2496.0</ele><time>2015-06-15T15:58:35Z</time></trkpt>
<trkpt lat="40.457473000" lon="-121.502177000"><ele>2496.0</ele><time>2015-06-15T15:58:45Z</time></trkpt>
<trkpt lat="40.457472000" lon="-121.502069000"><ele>2496.0</ele><time>2015-06-15T15:58:59Z</time></trkpt>
<trkpt lat="40.457557000" lon="-121.502044000"><ele>2496.0</ele><time>2015-06-15T15:59:11Z</time></trkpt>
<trkpt lat="40.457651000" lon="-121.502081000"><ele>2496.0</ele><time>2015-06-15T16:01:10Z</time></trkpt>
<trkpt lat="40.457748000" lon="-121.502051000"><ele>2496.0</ele><time>2015-06-15T16:14:43Z</time></trkpt>
<trkpt lat="40.457655000" lon="-121.502044000"><ele>2496.0</ele><time>2015-06-15T16:17:33Z</time></trkpt>
<trkpt lat="40.457569000" lon="-121.502016000"><ele>2496.0</ele><time>2015-06-15T16:17:44Z</time></trkpt>
<trkpt lat="40.457514000" lon="-121.501936000"><ele>2496.0</ele><time>2015-06-15T16:17:54Z</time></trkpt>
<trkpt lat="40.457527000" lon="-121.501819000"><ele>2496.0</ele><time>2015-06-15T16:18:03Z</time></trkpt>
<trkpt lat="40.457487000" lon="-121.501720000"><ele>2496.0</ele><time>2015-06-15T16:18:12Z</time></trkpt>
<trkpt lat="40.457415000" lon="-121.501657000"><ele>2496.0</ele><time>2015-06-15T16:18:19Z</time></trkpt>
<trkpt lat="40.457348000" lon="-121.501596000"><ele>2496.2</ele><time>2015-06-15T16:18:26Z</time></trkpt>
<trkpt lat="40.457263000" lon="-121.501504000"><ele>2496.4</ele><time>2015-06-15T16:18:56Z</time></trkpt>
<trkpt lat="40.457197000" lon="-121.501425000"><ele>2496.5</ele><time>2015-06-15T16:19:07Z</time></trkpt>
<trkpt lat="40.457164000" lon="-121.501306000"><ele>2496.7</ele><time>2015-06-15T16:19:47Z</time></trkpt>
<trkpt lat="40.457136000" lon="-121.501194000"><ele>2496.9</ele><time>2015-06-15T16:19:58Z</time></trkpt>
<trkpt lat="40.457109000" lon="-121.501091000"><ele>2497.1</ele><time>2015-06-15T16:20:07Z</time></trkpt>
<trkpt lat="40.457102000" lon="-121.500977000"><ele>2497.3</ele><time>2015-06-15T16:20:30Z</time></trkpt>
<trkpt lat="40.457140000" lon="-121.500877000"><ele>2497.5</ele><time>2015-06-15T16:20:39Z</time></trkpt>
<trkpt lat="40.457202000" lon="-121.500800000"><ele>2497.6</ele><time>2015-06-15T16:21:12Z</time></trkpt>
<trkpt lat="40.457322000" lon="-121.500755000"><ele>2497.8</ele><time>2015-06-15T16:22:21Z</time></trkpt>
<trkpt lat="40.457410000" lon="-121.500730000"><ele>2498.0</ele><time>2015-06-15T16:22:30Z</time></trkpt>
<trkpt lat="40.457493000" lon="-121.500743000"><ele>2498.0</ele><time>2015-06-15T16:22:38Z</time></trkpt>
<trkpt lat="40.457581000" lon="-121.500750000"><ele>2498.0</ele><time>2015-06-15T16:22:48Z</time></trkpt>
<trkpt lat="40.457482000" lon="-121.500733000"><ele>2498.0</ele><time>2015-06-15T16:24:46Z</time></trkpt>
<trkpt lat="40.457568000" lon="-121.500717000"><ele>2499.4</ele><time>2015-06-15T16:25:33Z</time></trkpt>
<trkpt lat="40.457647000" lon="-121.500764000"><ele>2500.7</ele><time>2015-06-15T16:25:45Z</time></trkpt>
<trkpt lat="40.457733000" lon="-121.500789000"><ele>2502.1</ele><time>2015-06-15T16:25:54Z</time></trkpt>
<trkpt lat="40.457822000" lon="-121.500802000"><ele>2502.1</ele><time>2015-06-15T16:26:02Z</time></trkpt>
<trkpt lat="40.457912000" lon="-121.500815000"><ele>2502.1</ele><time>2015-06-15T16:26:10Z</time></trkpt>
<trkpt lat="40.457997000" lon="-121.500806000"><ele>2502.1</ele><time>2015-06-15T16:26:18Z</time></trkpt>
<trkpt lat="40.458084000" lon="-121.500822000"><ele>2502.1</ele><time>2015-06-15T16:26:27Z</time></trkpt>
<trkpt lat="40.458005000" lon="-121.500777000"><ele>2502.1</ele><time>2015-06-15T16:31:49Z</time></trkpt>
<trkpt lat="40.457919000" lon="-121.500784000"><ele>2502.1</ele><time>2015-06-15T16:32:33Z</time></trkpt>
<trkpt lat="40.457838000" lon="-121.500772000"><ele>2502.1</ele><time>2015-06-15T16:32:44Z</time></trkpt>
<trkpt lat="40.457754000" lon="-121.500749000"><ele>2502.1</ele><time>2015-06-15T16:32:52Z</time></trkpt>
<trkpt lat="40.457671000" lon="-121.500720000"><ele>2500.7</ele><time>2015-06-15T16:33:00Z</time></trkpt>
<trkpt lat="40.457589000" lon="-121.500712000"><ele>2499.4</ele><time>2015-06-15T16:33:08Z</time></trkpt>
<trkpt lat="40.457508000" lon="-121.500711000"><ele>2498.0</ele><time>2015-06-15T16:33:17Z</time></trkpt>
<trkpt lat="40.457418000" lon="-121.500712000"><ele>2498.0</ele><time>2015-06-15T16:33:25Z</time></trkpt>
<trkpt lat="40.457331000" lon="-121.500726000"><ele>2498.0</ele><time>2015-06-15T16:33:41Z</time></trkpt>
<trkpt lat="40.457243000" lon="-121.500752000"><ele>2497.8</ele><time>2015-06-15T16:33:52Z</time></trkpt>
<trkpt lat="40.457156000" lon="-121.500815000"><ele>2497.6</ele><time>2015-06-15T16:34:25Z</time></trkpt>
<trkpt lat="40.457112000" lon="-121.500916000"><ele>2497.5</ele><time>2015-06-15T16:34:44Z</time></trkpt>
<trkpt lat="40.457126000" lon="-121.501042000"><ele>2497.3</ele><time>2015-06-15T16:35:21Z</time></trkpt>
<trkpt lat="40.457150000" lon="-121.501145000"><ele>2497.1</ele><time>2015-06-15T16:35:31Z</time></trkpt>
<trkpt lat="40.457173000" lon="-121.501247000"><ele>2496.9</ele><time>2015-06-15T16:35:41Z</time></trkpt>
<trkpt lat="40.457211000" lon="-121.501345000"><ele>2496.7</ele><time>2015-06-15T16:35:49Z</time></trkpt>
<trkpt lat="40.457261000" lon="-121.501433000"><ele>2496.5</ele><time>2015-06-15T16:35:58Z</time></trkpt>
<trkpt lat="40.457325000" lon="-121.501507000"><ele>2496.4</ele><time>2015-06-15T16:36:06Z</time></trkpt>
<trkpt lat="40.457393000" lon="-121.501573000"><ele>2496.2</ele><time>2015-06-15T16:36:13Z</time></trkpt>
<trkpt lat="40.457461000" lon="-121.501644000"><ele>2496.0</ele><time>2015-06-15T16:36:22Z</time></trkpt>
<trkpt lat="40.457526000" lon="-121.501716000"><ele>2496.0</ele><time>2015-06-15T16:36:31Z</time></trkpt>
<trkpt lat="40.457524000" lon="-121.501830000"><ele>2496.0</ele><time>2015-06-15T16:36:45Z</time></trkpt>
<trkpt lat="40.457514000" lon="-121.501938000"><ele>2496.0</ele><time>2015-06-15T16:36:55Z</time></trkpt>
<trkpt lat="40.457504000" lon="-121.502045000"><ele>2496.0</ele><time>2015-06-15T16:37:04Z</time></trkpt>
<trkpt lat="40.457496000" lon="-121.502153000"><ele>2496.0</ele><time>2015-06-15T16:37:13Z</time></trkpt>
<trkpt lat="40.457478000" lon="-121.502266000"><ele>2496.0</ele><time>2015-06-15T16:37:22Z</time></trkpt>
<trkpt lat="40.457379000" lon="-121.502344000"><ele>2496.0</ele><time>2015-06-15T16:37:38Z</time></trkpt>
<trkpt lat="40.457323000" lon="-121.502430000"><ele>2496.0</ele><time>2015-06-15T16:37:48Z</time></trkpt>
<trkpt lat="40.457260000" lon="-121.502499000"><ele>2496.0</ele><time>2015-06-15T16:37:59Z</time></trkpt>
<trkpt lat="40.457204000" lon="-121.502578000"><ele>2498.2</ele><time>2015-06-15T16:38:10Z</time></trkpt>
<trkpt lat="40.457219000" lon="-121.502684000"><ele>2500.4</ele><time>2015-06-15T16:38:22Z</time></trkpt>
<trkpt lat="40.457155000" lon="-121.502749000"><ele>2502.5</ele><time>2015-06-15T16:38:48Z</time></trkpt>
<trkpt lat="40.457074000" lon="-121.502716000"><ele>2503.5</ele><time>2015-06-15T16:39:07Z</time></trkpt>
<trkpt lat="40.456965000" lon="-121.502713000"><ele>2504.5</ele><time>2015-06-15T16:39:46Z</time></trkpt>
<trkpt lat="40.456973000" lon="-121.502853000"><ele>2505.5</ele><time>2015-06-15T16:41:06Z</time></trkpt>
<trkpt lat="40.457028000" lon="-121.502986000"><ele>2506.5</ele><time>2015-06-15T16:41:24Z</time></trkpt>
<trkpt lat="40.457100000" lon="-121.503043000"><ele>2507.5</ele><time>2015-06-15T16:41:33Z</time></trkpt>
<trkpt lat="40.457173000" lon="-121.503105000"><ele>2508.5</ele><time>2015-06-15T16:41:40Z</time></trkpt>
<trkpt lat="40.457264000" lon="-121.503196000"><ele>2511.4</ele><time>2015-06-15T16:41:55Z</time></trkpt>
<trkpt lat="40.457317000" lon="-121.503282000"><ele>2514.2</ele><time>2015-06-15T16:42:10Z</time></trkpt>
<trkpt lat="40.457329000" lon="-121.503407000"><ele>2514.8</ele><time>2015-06-15T16:42:29Z</time></trkpt>
<trkpt lat="40.457342000" lon="-121.503533000"><ele>2515.5</ele><time>2015-06-15T16:42:53Z</time></trkpt>
<trkpt lat="40.457390000" lon="-121.503652000"><ele>2516.1</ele><time>2015-06-15T16:43:54Z</time></trkpt>
<trkpt lat="40.457484000" lon="-121.503694000"><ele>2517.9</ele><time>2015-06-15T16:44:29Z</time></trkpt>
<trkpt lat="40.457527000" lon="-121.503787000"><ele>2519.7</ele><time>2015-06-15T16:44:40Z</time></trkpt>
<trkpt lat="40.457579000" lon="-121.503868000"><ele>2521.5</ele><time>2015-06-15T16:44:48Z</time></trkpt>
<trkpt lat="40.457607000" lon="-121.503971000"><ele>2523.4</ele><time>2015-06-15T16:44:56Z</time></trkpt>
<trkpt lat="40.457550000" lon="-121.504062000"><ele>2525.2</ele><time>2015-06-15T16:45:07Z</time></trkpt>
<trkpt lat="40.457480000" lon="-121.504120000"><ele>2527.0</ele><time>2015-06-15T16:45:16Z</time></trkpt>
<trkpt lat="40.457398000" lon="-121.504135000"><ele>2529.0</ele><time>2015-06-15T16:45:23Z</time></trkpt>
<trkpt lat="40.457313000" lon="-121.504146000"><ele>2531.0</ele><time>2015-06-15T16:45:31Z</time></trkpt>
<trkpt lat="40.457296000" lon="-121.504259000"><ele>2533.0</ele><time>2015-06-15T16:45:43Z</time></trkpt>
<trkpt lat="40.457338000" lon="-121.504360000"><ele>2535.0</ele><time>2015-06-15T16:45:53Z</time></trkpt>
<trkpt lat="40.457392000" lon="-121.504458000"><ele>2537.0</ele><time>2015-06-15T16:46:05Z</time></trkpt>
<trkpt lat="40.457422000" lon="-121.504560000"><ele>2539.0</ele><time>2015-06-15T16:46:15Z</time></trkpt>
<trkpt lat="40.457425000" lon="-121.504668000"><ele>2541.0</ele><time>2015-06-15T16:46:25Z</time></trkpt>
<trkpt lat="40.457457000" lon="-121.504766000"><ele>2543.0</ele><time>2015-06-15T16:46:38Z</time></trkpt>
<trkpt lat="40.457518000" lon="-121.504846000"><ele>2544.5</ele><time>2015-06-15T16:46:59Z</time></trkpt>
<trkpt lat="40.457585000" lon="-121.504915000"><ele>2546.1</ele><time>2015-06-15T16:47:11Z</time></trkpt>
<trkpt lat="40.457673000" lon="-121.504944000"><ele>2547.6</ele><time>2015-06-15T16:47:20Z</time></trkpt>
<trkpt lat="40.457758000" lon="-121.504933000"><ele>2547.2</ele><time>2015-06-15T16:47:29Z</time></trkpt>
<trkpt lat="40.457865000" lon="-121.504966000"><ele>2546.7</ele><time>2015-06-15T16:47:45Z</time></trkpt>
<trkpt lat="40.457943000" lon="-121.504998000"><ele>2546.3</ele><time>2015-06-15T16:48:00Z</time></trkpt>
<trkpt lat="40.458032000" lon="-121.505009000"><ele>2545.8</ele><time>2015-06-15T16:48:10Z</time></trkpt>
<trkpt lat="40.458112000" lon="-121.505032000"><ele>2545.4</ele><time>2015-06-15T16:48:20Z</time></trkpt>
<trkpt lat="40.458192000" lon="-121.505049000"><ele>2544.9</ele><time>2015-06-15T16:48:30Z</time></trkpt>
<trkpt lat="40.458279000" lon="-121.505063000"><ele>2545.2</ele><time>2015-06-15T16:48:42Z</time></trkpt>
<trkpt lat="40.458364000" lon="-121.505076000"><ele>2545.5</ele><time>2015-06-15T16:48:52Z</time></trkpt>
<trkpt lat="40.458441000" lon="-121.505118000"><ele>2546.2</ele><time>2015-06-15T16:49:23Z</time></trkpt>
<trkpt lat="40.458511000" lon="-121.505178000"><ele>2547.6</ele><time>2015-06-15T16:49:33Z</time></trkpt>
<trkpt lat="40.458587000" lon="-121.505226000"><ele>2549.1</ele><time>2015-06-15T16:49:43Z</time></trkpt>
<trkpt lat="40.458620000" lon="-121.505325000"><ele>2550.5</ele><time>2015-06-15T16:49:54Z</time></trkpt>
<trkpt lat="40.458623000" lon="-121.505432000"><ele>2552.0</ele><time>2015-06-15T16:50:03Z</time></trkpt>
<trkpt lat="40.458718000" lon="-121.505509000"><ele>2553.5</ele><time>2015-06-15T16:50:25Z</time></trkpt>
<trkpt lat="40.458803000" lon="-121.505517000"><ele>2554.9</ele><time>2015-06-15T16:50:40Z</time></trkpt>
<trkpt lat="40.458888000" lon="-121.505510000"><ele>2556.4</ele><time>2015-06-15T16:50:51Z</time></trkpt>
<trkpt lat="40.458968000" lon="-121.505540000"><ele>2557.8</ele><time>2015-06-15T16:51:02Z</time></trkpt>
<trkpt lat="40.459042000" lon="-121.505584000"><ele>2558.5</ele><time>2015-06-15T16:51:11Z</time></trkpt>
<trkpt lat="40.459114000" lon="-121.505646000"><ele>2559.3</ele><time>2015-06-15T16:51:19Z</time></trkpt>
<trkpt lat="40.459182000" lon="-121.505730000"><ele>2560.0</ele><time>2015-06-15T16:51:27Z</time></trkpt>
<trkpt lat="40.459252000" lon="-121.505793000"><ele>2558.2</ele><time>2015-06-15T16:51:36Z</time></trkpt>
<trkpt lat="40.459327000" lon="-121.505846000"><ele>2558.1</ele><time>2015-06-15T16:51:45Z</time></trkpt>
<trkpt lat="40.459391000" lon="-121.505929000"><ele>2558.0</ele><time>2015-06-15T16:51:54Z</time></trkpt>
<trkpt lat="40.459457000" lon="-121.506006000"><ele>2557.9</ele><time>2015-06-15T16:52:03Z</time></trkpt>
<trkpt lat="40.459521000" lon="-121.506083000"><ele>2557.8</ele><time>2015-06-15T16:52:12Z</time></trkpt>
<trkpt lat="40.459586000" lon="-121.506163000"><ele>2557.7</ele><time>2015-06-15T16:52:23Z</time></trkpt>
<trkpt lat="40.459648000" lon="-121.506233000"><ele>2557.6</ele><time>2015-06-15T16:52:32Z</time></trkpt>
<trkpt lat="40.459714000" lon="-121.506304000"><ele>2557.5</ele><time>2015-06-15T16:52:40Z</time></trkpt>
<trkpt lat="40.459767000" lon="-121.506405000"><ele>2557.5</ele><time>2015-06-15T16:52:47Z</time></trkpt>
<trkpt lat="40.459806000" lon="-121.506509000"><ele>2557.4</ele><time>2015-06-15T16:52:54Z</time></trkpt>
<trkpt lat="40.459861000" lon="-121.506598000"><ele>2557.3</ele><time>2015-06-15T16:53:04Z</time></trkpt>
<trkpt lat="40.459934000" lon="-121.506666000"><ele>2559.0</ele><time>2015-06-15T16:53:12Z</time></trkpt>
<trkpt lat="40.459993000" lon="-121.506748000"><ele>2557.5</ele><time>2015-06-15T16:53:20Z</time></trkpt>
<trkpt lat="40.460059000" lon="-121.506818000"><ele>2555.9</ele><time>2015-06-15T16:53:28Z</time></trkpt>
<trkpt lat="40.460132000" lon="-121.506862000"><ele>2554.4</ele><time>2015-06-15T16:53:36Z</time></trkpt>
<trkpt lat="40.460171000" lon="-121.506966000"><ele>2552.8</ele><time>2015-06-15T16:53:43Z</time></trkpt>
<trkpt lat="40.460206000" lon="-121.507063000"><ele>2551.3</ele><time>2015-06-15T16:53:51Z</time></trkpt>
<trkpt lat="40.460260000" lon="-121.507150000"><ele>2550.9</ele><time>2015-06-15T16:53:59Z</time></trkpt>
<trkpt lat="40.460309000" lon="-121.507248000"><ele>2550.5</ele><time>2015-06-15T16:54:07Z</time></trkpt>
<trkpt lat="40.460354000" lon="-121.507354000"><ele>2550.2</ele><time>2015-06-15T16:54:15Z</time></trkpt>
<trkpt lat="40.460402000" lon="-121.507451000"><ele>2548.6</ele><time>2015-06-15T16:54:24Z</time></trkpt>
<trkpt lat="40.460456000" lon="-121.507551000"><ele>2547.1</ele><time>2015-06-15T16:54:32Z</time></trkpt>
<trkpt lat="40.460495000" lon="-121.507656000"><ele>2545.5</ele><time>2015-06-15T16:54:40Z</time></trkpt>
<trkpt lat="40.460536000" lon="-121.507755000"><ele>2545.5</ele><time>2015-06-15T16:54:48Z</time></trkpt>
<trkpt lat="40.460591000" lon="-121.507843000"><ele>2545.5</ele><time>2015-06-15T16:54:57Z</time></trkpt>
<trkpt lat="40.460639000" lon="-121.507941000"><ele>2545.5</ele><time>2015-06-15T16:55:05Z</time></trkpt>
<trkpt lat="40.460628000" lon="-121.508055000"><ele>2545.5</ele><time>2015-06-15T16:55:12Z</time></trkpt>
<trkpt lat="40.460639000" lon="-121.508171000"><ele>2545.5</ele><time>2015-06-15T16:55:20Z</time></trkpt>
<trkpt lat="40.460675000" lon="-121.508271000"><ele>2544.4</ele><time>2015-06-15T16:55:28Z</time></trkpt>
<trkpt lat="40.460723000" lon="-121.508359000"><ele>2542.7</ele><time>2015-06-15T16:55:38Z</time></trkpt>
<trkpt lat="40.460807000" lon="-121.508402000"><ele>2541.1</ele><time>2015-06-15T16:55:47Z</time></trkpt>
<trkpt lat="40.460861000" lon="-121.508495000"><ele>2540.6</ele><time>2015-06-15T16:55:55Z</time></trkpt>
<trkpt lat="40.460891000" lon="-121.508608000"><ele>2540.2</ele><time>2015-06-15T16:56:03Z</time></trkpt>
<trkpt lat="40.460907000" lon="-121.508717000"><ele>2539.7</ele><time>2015-06-15T16:56:12Z</time></trkpt>
<trkpt lat="40.460889000" lon="-121.508860000"><ele>2539.3</ele><time>2015-06-15T16:56:28Z</time></trkpt>
<trkpt lat="40.460881000" lon="-121.508975000"><ele>2538.8</ele><time>2015-06-15T16:56:38Z</time></trkpt>
<trkpt lat="40.460867000" lon="-121.509096000"><ele>2537.2</ele><time>2015-06-15T16:56:46Z</time></trkpt>
<trkpt lat="40.460850000" lon="-121.509203000"><ele>2535.5</ele><time>2015-06-15T16:56:55Z</time></trkpt>
<trkpt lat="40.460848000" lon="-121.509319000"><ele>2533.9</ele><time>2015-06-15T16:57:03Z</time></trkpt>
<trkpt lat="40.460874000" lon="-121.509427000"><ele>2532.3</ele><time>2015-06-15T16:57:12Z</time></trkpt>
<trkpt lat="40.460923000" lon="-121.509519000"><ele>2531.1</ele><time>2015-06-15T16:57:22Z</time></trkpt>
<trkpt lat="40.460942000" lon="-121.509632000"><ele>2529.9</ele><time>2015-06-15T16:57:34Z</time></trkpt>
<trkpt lat="40.460921000" lon="-121.509752000"><ele>2528.7</ele><time>2015-06-15T16:57:42Z</time></trkpt>
<trkpt lat="40.460878000" lon="-121.509853000"><ele>2527.5</ele><time>2015-06-15T16:57:48Z</time></trkpt>
<trkpt lat="40.460839000" lon="-121.509996000"><ele>2526.4</ele><time>2015-06-15T16:59:24Z</time></trkpt>
<trkpt lat="40.460881000" lon="-121.509895000"><ele>2525.2</ele><time>2015-06-15T17:01:08Z</time></trkpt>
<trkpt lat="40.460948000" lon="-121.509832000"><ele>2524.0</ele><time>2015-06-15T17:01:18Z</time></trkpt>
<trkpt lat="40.461008000" lon="-121.509757000"><ele>2524.0</ele><time>2015-06-15T17:01:27Z</time></trkpt>
<trkpt lat="40.461088000" lon="-121.509719000"><ele>2525.1</ele><time>2015-06-15T17:01:36Z</time></trkpt>
<trkpt lat="40.461176000" lon="-121.509697000"><ele>2526.2</ele><time>2015-06-15T17:01:50Z</time></trkpt>
<trkpt lat="40.461262000" lon="-121.509660000"><ele>2527.3</ele><time>2015-06-15T17:01:59Z</time></trkpt>
<trkpt lat="40.461339000" lon="-121.509619000"><ele>2528.4</ele><time>2015-06-15T17:02:07Z</time></trkpt>
<trkpt lat="40.461418000" lon="-121.509570000"><ele>2529.5</ele><time>2015-06-15T17:02:15Z</time></trkpt>
<trkpt lat="40.461479000" lon="-121.509484000"><ele>2530.5</ele><time>2015-06-15T17:02:24Z</time></trkpt>
<trkpt lat="40.461503000" lon="-121.509380000"><ele>2531.6</ele><time>2015-06-15T17:02:33Z</time></trkpt>
<trkpt lat="40.461567000" lon="-121.509303000"><ele>2532.7</ele><time>2015-06-15T17:02:40Z</time></trkpt>
<trkpt lat="40.461636000" lon="-121.509235000"><ele>2533.8</ele><time>2015-06-15T17:02:48Z</time></trkpt>
<trkpt lat="40.461712000" lon="-121.509173000"><ele>2534.2</ele><time>2015-06-15T17:02:57Z</time></trkpt>
<trkpt lat="40.461787000" lon="-121.509112000"><ele>2534.5</ele><time>2015-06-15T17:03:07Z</time></trkpt>
<trkpt lat="40.461876000" lon="-121.509120000"><ele>2533.8</ele><time>2015-06-15T17:03:16Z</time></trkpt>
<trkpt lat="40.461957000" lon="-121.509110000"><ele>2533.1</ele><time>2015-06-15T17:03:23Z</time></trkpt>
<trkpt lat="40.462043000" lon="-121.509090000"><ele>2532.4</ele><time>2015-06-15T17:03:31Z</time></trkpt>
<trkpt lat="40.462125000" lon="-121.509095000"><ele>2531.6</ele><time>2015-06-15T17:03:39Z</time></trkpt>
<trkpt lat="40.462214000" lon="-121.509108000"><ele>2530.9</ele><time>2015-06-15T17:03:49Z</time></trkpt>
<trkpt lat="40.462303000" lon="-121.509109000"><ele>2530.2</ele><time>2015-06-15T17:03:58Z</time></trkpt>
<trkpt lat="40.462373000" lon="-121.509052000"><ele>2529.5</ele><time>2015-06-15T17:04:06Z</time></trkpt>
<trkpt lat="40.462438000" lon="-121.508986000"><ele>2528.7</ele><time>2015-06-15T17:04:13Z</time></trkpt>
<trkpt lat="40.462523000" lon="-121.508965000"><ele>2528.2</ele><time>2015-06-15T17:04:21Z</time></trkpt>
<trkpt lat="40.462606000" lon="-121.508962000"><ele>2528.4</ele><time>2015-06-15T17:04:28Z</time></trkpt>
<trkpt lat="40.462696000" lon="-121.508982000"><ele>2528.5</ele><time>2015-06-15T17:04:37Z</time></trkpt>
<trkpt lat="40.462783000" lon="-121.508955000"><ele>2528.7</ele><time>2015-06-15T17:04:45Z</time></trkpt>
<trkpt lat="40.462875000" lon="-121.508948000"><ele>2528.9</ele><time>2015-06-15T17:04:52Z</time></trkpt>
<trkpt lat="40.462956000" lon="-121.508982000"><ele>2529.1</ele><time>2015-06-15T17:04:59Z</time></trkpt>
<trkpt lat="40.463038000" lon="-121.509011000"><ele>2529.3</ele><time>2015-06-15T17:05:06Z</time></trkpt>
<trkpt lat="40.463120000" lon="-121.509035000"><ele>2529.5</ele><time>2015-06-15T17:05:15Z</time></trkpt>
<trkpt lat="40.463196000" lon="-121.509076000"><ele>2529.6</ele><time>2015-06-15T17:05:23Z</time></trkpt>
<trkpt lat="40.463276000" lon="-121.509136000"><ele>2527.7</ele><time>2015-06-15T17:05:32Z</time></trkpt>
<trkpt lat="40.463338000" lon="-121.509218000"><ele>2525.8</ele><time>2015-06-15T17:05:40Z</time></trkpt>
<trkpt lat="40.463356000" lon="-121.509330000"><ele>2523.7</ele><time>2015-06-15T17:05:51Z</time></trkpt>
<trkpt lat="40.463373000" lon="-121.509449000"><ele>2521.6</ele><time>2015-06-15T17:06:00Z</time></trkpt>
<trkpt lat="40.463413000" lon="-121.509546000"><ele>2520.7</ele><time>2015-06-15T17:06:07Z</time></trkpt>
<trkpt lat="40.463477000" lon="-121.509613000"><ele>2519.8</ele><time>2015-06-15T17:06:14Z</time></trkpt>
<trkpt lat="40.463559000" lon="-121.509663000"><ele>2518.9</ele><time>2015-06-15T17:06:23Z</time></trkpt>
<trkpt lat="40.463626000" lon="-121.509721000"><ele>2518.0</ele><time>2015-06-15T17:06:30Z</time></trkpt>
<trkpt lat="40.463692000" lon="-121.509788000"><ele>2517.1</ele><time>2015-06-15T17:06:37Z</time></trkpt>
<trkpt lat="40.463758000" lon="-121.509852000"><ele>2516.2</ele><time>2015-06-15T17:06:44Z</time></trkpt>
<trkpt lat="40.463831000" lon="-121.509903000"><ele>2515.3</ele><time>2015-06-15T17:06:52Z</time></trkpt>
<trkpt lat="40.463915000" lon="-121.509949000"><ele>2516.5</ele><time>2015-06-15T17:07:02Z</time></trkpt>
<trkpt lat="40.463997000" lon="-121.509970000"><ele>2517.6</ele><time>2015-06-15T17:07:10Z</time></trkpt>
<trkpt lat="40.464083000" lon="-121.509995000"><ele>2518.8</ele><time>2015-06-15T17:07:20Z</time></trkpt>
<trkpt lat="40.464166000" lon="-121.510025000"><ele>2520.0</ele><time>2015-06-15T17:07:28Z</time></trkpt>
<trkpt lat="40.464255000" lon="-121.510041000"><ele>2520.6</ele><time>2015-06-15T17:07:36Z</time></trkpt>
<trkpt lat="40.464337000" lon="-121.510048000"><ele>2521.3</ele><time>2015-06-15T17:07:45Z</time></trkpt>
<trkpt lat="40.464421000" lon="-121.510034000"><ele>2521.9</ele><time>2015-06-15T17:07:53Z</time></trkpt>
<trkpt lat="40.464511000" lon="-121.510050000"><ele>2522.5</ele><time>2015-06-15T17:08:02Z</time></trkpt>
<trkpt lat="40.464595000" lon="-121.510081000"><ele>2523.2</ele><time>2015-06-15T17:08:08Z</time></trkpt>
<trkpt lat="40.464672000" lon="-121.510136000"><ele>2523.8</ele><time>2015-06-15T17:08:15Z</time></trkpt>
<trkpt lat="40.464763000" lon="-121.510153000"><ele>2520.7</ele><time>2015-06-15T17:08:25Z</time></trkpt>
<trkpt lat="40.464842000" lon="-121.510194000"><ele>2517.6</ele><time>2015-06-15T17:08:33Z</time></trkpt>
<trkpt lat="40.464923000" lon="-121.510232000"><ele>2514.5</ele><time>2015-06-15T17:08:41Z</time></trkpt>
<trkpt lat="40.464998000" lon="-121.510275000"><ele>2511.5</ele><time>2015-06-15T17:08:49Z</time></trkpt>
<trkpt lat="40.465072000" lon="-121.510319000"><ele>2508.4</ele><time>2015-06-15T17:08:57Z</time></trkpt>
<trkpt lat="40.465147000" lon="-121.510380000"><ele>2505.7</ele><time>2015-06-15T17:09:06Z</time></trkpt>
<trkpt lat="40.465220000" lon="-121.510445000"><ele>2503.1</ele><time>2015-06-15T17:09:14Z</time></trkpt>
<trkpt lat="40.465305000" lon="-121.510517000"><ele>2500.5</ele><time>2015-06-15T17:09:24Z</time></trkpt>
<trkpt lat="40.465376000" lon="-121.510570000"><ele>2497.8</ele><time>2015-06-15T17:09:32Z</time></trkpt>
<trkpt lat="40.465460000" lon="-121.510611000"><ele>2495.2</ele><time>2015-06-15T17:09:39Z</time></trkpt>
<trkpt lat="40.465553000" lon="-121.510623000"><ele>2492.5</ele><time>2015-06-15T17:09:46Z</time></trkpt>
<trkpt lat="40.465640000" lon="-121.510617000"><ele>2493.6</ele><time>2015-06-15T17:09:53Z</time></trkpt>
<trkpt lat="40.465723000" lon="-121.510656000"><ele>2494.7</ele><time>2015-06-15T17:10:01Z</time></trkpt>
<trkpt lat="40.465807000" lon="-121.510653000"><ele>2495.8</ele><time>2015-06-15T17:10:08Z</time></trkpt>
<trkpt lat="40.465899000" lon="-121.510649000"><ele>2497.1</ele><time>2015-06-15T17:10:15Z</time></trkpt>
<trkpt lat="40.465985000" lon="-121.510652000"><ele>2498.4</ele><time>2015-06-15T17:10:21Z</time></trkpt>
<trkpt lat="40.466069000" lon="-121.510702000"><ele>2498.5</ele><time>2015-06-15T17:10:29Z</time></trkpt>
<trkpt lat="40.466140000" lon="-121.510761000"><ele>2498.7</ele><time>2015-06-15T17:10:36Z</time></trkpt>
<trkpt lat="40.466224000" lon="-121.510807000"><ele>2498.9</ele><time>2015-06-15T17:10:59Z</time></trkpt>
<trkpt lat="40.466304000" lon="-121.510838000"><ele>2498.8</ele><time>2015-06-15T17:11:06Z</time></trkpt>
<trkpt lat="40.466391000" lon="-121.510857000"><ele>2498.7</ele><time>2015-06-15T17:11:15Z</time></trkpt>
<trkpt lat="40.466415000" lon="-121.510964000"><ele>2498.6</ele><time>2015-06-15T17:11:26Z</time></trkpt>
<trkpt lat="40.466371000" lon="-121.511064000"><ele>2498.5</ele><time>2015-06-15T17:11:35Z</time></trkpt>
<trkpt lat="40.466327000" lon="-121.511154000"><ele>2498.5</ele><time>2015-06-15T17:11:43Z</time></trkpt>
<trkpt lat="40.466321000" lon="-121.511264000"><ele>2498.4</ele><time>2015-06-15T17:11:51Z</time></trkpt>
<trkpt lat="40.466327000" lon="-121.511379000"><ele>2498.1</ele><time>2015-06-15T17:11:59Z</time></trkpt>
<trkpt lat="40.466332000" lon="-121.511490000"><ele>2497.8</ele><time>2015-06-15T17:12:07Z</time></trkpt>
<trkpt lat="40.466337000" lon="-121.511604000"><ele>2497.5</ele><time>2015-06-15T17:12:15Z</time></trkpt>
<trkpt lat="40.466330000" lon="-121.511726000"><ele>2497.3</ele><time>2015-06-15T17:12:24Z</time></trkpt>
<trkpt lat="40.466342000" lon="-121.511834000"><ele>2496.8</ele><time>2015-06-15T17:12:32Z</time></trkpt>
<trkpt lat="40.466408000" lon="-121.511901000"><ele>2496.6</ele><time>2015-06-15T17:12:40Z</time></trkpt>
<trkpt lat="40.466491000" lon="-121.511935000"><ele>2496.5</ele><time>2015-06-15T17:12:50Z</time></trkpt>
<trkpt lat="40.466574000" lon="-121.511935000"><ele>2496.3</ele><time>2015-06-15T17:13:00Z</time></trkpt>
<trkpt lat="40.466660000" lon="-121.511971000"><ele>2496.1</ele><time>2015-06-15T17:13:09Z</time></trkpt>
<trkpt lat="40.466654000" lon="-121.512080000"><ele>2495.9</ele><time>2015-06-15T17:13:21Z</time></trkpt>
<trkpt lat="40.466627000" lon="-121.512188000"><ele>2495.7</ele><time>2015-06-15T17:13:30Z</time></trkpt>
<trkpt lat="40.466622000" lon="-121.512299000"><ele>2495.5</ele><time>2015-06-15T17:13:40Z</time></trkpt>
<trkpt lat="40.466670000" lon="-121.512397000"><ele>2495.4</ele><time>2015-06-15T17:13:52Z</time></trkpt>
<trkpt lat="40.466753000" lon="-121.512438000"><ele>2495.4</ele><time>2015-06-15T17:14:06Z</time></trkpt>
<trkpt lat="40.466836000" lon="-121.512488000"><ele>2495.4</ele><time>2015-06-15T17:14:15Z</time></trkpt>
<trkpt lat="40.466864000" lon="-121.512589000"><ele>2495.5</ele><time>2015-06-15T17:14:23Z</time></trkpt>
<trkpt lat="40.466886000" lon="-121.512707000"><ele>2495.7</ele><time>2015-06-15T17:14:31Z</time></trkpt>
<trkpt lat="40.466901000" lon="-121.512820000"><ele>2495.9</ele><time>2015-06-15T17:14:38Z</time></trkpt>
<trkpt lat="40.466892000" lon="-121.512934000"><ele>2496.1</ele><time>2015-06-15T17:14:45Z</time></trkpt>
<trkpt lat="40.466881000" lon="-121.513041000"><ele>2496.3</ele><time>2015-06-15T17:14:53Z</time></trkpt>
<trkpt lat="40.466873000" lon="-121.513156000"><ele>2496.5</ele><time>2015-06-15T17:15:01Z</time></trkpt>
<trkpt lat="40.466834000" lon="-121.513250000"><ele>2496.6</ele><time>2015-06-15T17:15:09Z</time></trkpt>
<trkpt lat="40.466783000" lon="-121.513339000"><ele>2497.3</ele><time>2015-06-15T17:15:16Z</time></trkpt>
<trkpt lat="40.466731000" lon="-121.513424000"><ele>2497.9</ele><time>2015-06-15T17:15:24Z</time></trkpt>
<trkpt lat="40.466671000" lon="-121.513504000"><ele>2498.4</ele><time>2015-06-15T17:15:33Z</time></trkpt>
<trkpt lat="40.466608000" lon="-121.513572000"><ele>2498.1</ele><time>2015-06-15T17:15:40Z</time></trkpt>
<trkpt lat="40.466530000" lon="-121.513627000"><ele>2497.8</ele><time>2015-06-15T17:15:48Z</time></trkpt>
<trkpt lat="40.466463000" lon="-121.513691000"><ele>2497.5</ele><time>2015-06-15T17:15:55Z</time></trkpt>
<trkpt lat="40.466392000" lon="-121.513759000"><ele>2497.3</ele><time>2015-06-15T17:16:03Z</time></trkpt>
<trkpt lat="40.466317000" lon="-121.513819000"><ele>2497.0</ele><time>2015-06-15T17:16:11Z</time></trkpt>
<trkpt lat="40.466254000" lon="-121.513903000"><ele>2496.7</ele><time>2015-06-15T17:16:19Z</time></trkpt>
<trkpt lat="40.466194000" lon="-121.513985000"><ele>2496.5</ele><time>2015-06-15T17:16:27Z</time></trkpt>
<trkpt lat="40.466118000" lon="-121.514048000"><ele>2496.2</ele><time>2015-06-15T17:16:34Z</time></trkpt>
<trkpt lat="40.466044000" lon="-121.514116000"><ele>2495.5</ele><time>2015-06-15T17:16:41Z</time></trkpt>
<trkpt lat="40.465970000" lon="-121.514186000"><ele>2494.9</ele><time>2015-06-15T17:16:48Z</time></trkpt>
<trkpt lat="40.465904000" lon="-121.514247000"><ele>2494.3</ele><time>2015-06-15T17:16:54Z</time></trkpt>
<trkpt lat="40.465838000" lon="-121.514321000"><ele>2494.4</ele><time>2015-06-15T17:17:01Z</time></trkpt>
<trkpt lat="40.465784000" lon="-121.514416000"><ele>2494.5</ele><time>2015-06-15T17:17:09Z</time></trkpt>
<trkpt lat="40.465736000" lon="-121.514514000"><ele>2494.5</ele><time>2015-06-15T17:17:17Z</time></trkpt>
<trkpt lat="40.465678000" lon="-121.514593000"><ele>2494.6</ele><time>2015-06-15T17:17:24Z</time></trkpt>
<trkpt lat="40.465672000" lon="-121.514705000"><ele>2494.7</ele><time>2015-06-15T17:19:43Z</time></trkpt>
<trkpt lat="40.465720000" lon="-121.514792000"><ele>2494.8</ele><time>2015-06-15T17:19:51Z</time></trkpt>
<trkpt lat="40.465699000" lon="-121.514913000"><ele>2494.9</ele><time>2015-06-15T17:20:38Z</time></trkpt>
<trkpt lat="40.465664000" lon="-121.514809000"><ele>2495.0</ele><time>2015-06-15T17:20:56Z</time></trkpt>
</trkseg>
</trk>
</gpx>

View File

@ -75,6 +75,7 @@ import {RandomPhotoSettingsComponent} from './settings/random-photo/random-photo
import {FixOrientationPipe} from './gallery/FixOrientationPipe';
import {VideoSettingsComponent} from './settings/video/video.settings.component';
import {DurationPipe} from './pipes/DurationPipe';
import {MapService} from './gallery/map/map.service';
@Injectable()
export class GoogleMapsConfig {
@ -183,6 +184,7 @@ export function translationsFactory(locale: string) {
UserService,
GalleryCacheService,
GalleryService,
MapService,
AuthenticationService,
ThumbnailLoaderService,
ThumbnailManagerService,

View File

@ -35,7 +35,8 @@
[directory]="directory"></app-gallery-directory>
</div>
<app-gallery-map *ngIf="isPhotoWithLocation && mapEnabled"
[photos]="_galleryService.content.value.directory.media"></app-gallery-map>
[photos]="_galleryService.content.value.directory.media"
[metaFiles]="_galleryService.content.value.directory.metaFile"></app-gallery-map>
<app-gallery-grid [photos]="_galleryService.content.value.directory.media"
[lightbox]="lightbox"></app-gallery-grid>
</div>
@ -60,7 +61,8 @@
</ol>
<app-gallery-map *ngIf="isPhotoWithLocation && mapEnabled"
[photos]="_galleryService.content.value.searchResult.media"></app-gallery-map>
[photos]="_galleryService.content.value.searchResult.media"
[metaFiles]="_galleryService.content.value.searchResult.metaFile"></app-gallery-map>
<div class="directories">
<app-gallery-directory *ngFor="let directory of directories"

View File

@ -10,6 +10,21 @@
[style.width.px]="mapDimension.width"
[style.height.px]="mapDimension.height"
[fitBounds]="true">
<agm-polyline *ngFor="let path of paths"
strokeColor="#007bff"
strokeOpacity="0.8"
strokeWeight="6">
<agm-polyline-point
*ngFor="let point of path"
[latitude]="point.latitude" [longitude]="point.longitude">
</agm-polyline-point>
</agm-polyline>
<agm-marker
*ngFor="let path of paths"
[latitude]="path[0].latitude"
[longitude]="path[0].longitude"
[agmFitBounds]="true">
</agm-marker>
<agm-marker
*ngFor="let photo of mapPhotos"
[latitude]="photo.latitude"

View File

@ -9,6 +9,11 @@ import {Media} from '../../Media';
import {PageHelper} from '../../../model/page.helper';
import {OrientationTypes} from 'ts-exif-parser';
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
import {FileDTO} from '../../../../../common/entities/FileDTO';
import {NetworkService} from '../../../model/network/network.service';
import {Utils} from '../../../../../common/Utils';
import {Config} from '../../../../../common/config/public/Config';
import {MapPath, MapService} from '../map.service';
@Component({
@ -18,7 +23,8 @@ import {MediaDTO} from '../../../../../common/entities/MediaDTO';
})
export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
@Input() photos: Array<PhotoDTO>;
@Input() photos: PhotoDTO[];
@Input() gpxFiles: FileDTO[];
private startPosition = null;
public lightboxDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
public mapDimension: Dimension = <Dimension>{top: 0, left: 0, width: 0, height: 0};
@ -26,6 +32,7 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
public controllersVisible = false;
public opacity = 1.0;
mapPhotos: MapPhoto[] = [];
paths: MapPath[][] = [];
mapCenter = {latitude: 0, longitude: 0};
@ViewChild('root') elementRef: ElementRef;
@ -35,6 +42,7 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
constructor(public fullScreenService: FullScreenService,
private thumbnailService: ThumbnailManagerService,
private mapService: MapService,
private mapsAPILoader: MapsAPILoader) {
}
@ -139,6 +147,22 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
return obj;
});
if (this.gpxFiles) {
this.loadGPXFiles().catch(console.error);
}
}
private async loadGPXFiles(): Promise<void> {
this.paths = [];
for (let i = 0; i < this.gpxFiles.length; i++) {
const file = this.gpxFiles[i];
const path = await this.mapService.getMapPath(file);
if (file !== this.gpxFiles[i]) { // check race condition
return;
}
this.paths.push(path);
}
}

View File

@ -1,5 +1,5 @@
<ng-template [ngIf]="mapPhotos.length>0">
<app-gallery-map-lightbox [photos]="photos"></app-gallery-map-lightbox>
<app-gallery-map-lightbox [photos]="photos" [gpxFiles]="metaFiles"></app-gallery-map-lightbox>
<div id="map" #map>
<agm-map
[disableDefaultUI]="true"

View File

@ -5,6 +5,7 @@ import {GalleryMapLightboxComponent} from './lightbox/lightbox.map.gallery.compo
import {ThumbnailManagerService} from '../thumnailManager.service';
import {FullScreenService} from '../fullscreen.service';
import {LatLngBounds, MapsAPILoader, AgmMap} from '@agm/core';
import {FileDTO} from '../../../../common/entities/FileDTO';
@Component({
selector: 'app-gallery-map',
@ -13,7 +14,8 @@ import {LatLngBounds, MapsAPILoader, AgmMap} from '@agm/core';
})
export class GalleryMapComponent implements OnChanges, IRenderable, AfterViewInit {
@Input() photos: Array<PhotoDTO>;
@Input() photos: PhotoDTO[];
@Input() metaFiles: FileDTO[];
@ViewChild(GalleryMapLightboxComponent) mapLightbox: GalleryMapLightboxComponent;
mapPhotos: Array<{ latitude: number, longitude: number }> = [];

View File

@ -0,0 +1,34 @@
import {Injectable} from '@angular/core';
import {NetworkService} from '../../model/network/network.service';
import {FileDTO} from '../../../../common/entities/FileDTO';
import {Utils} from '../../../../common/Utils';
@Injectable()
export class MapService {
constructor(private networkService: NetworkService) {
}
public async getMapPath(file: FileDTO): Promise<MapPath[]> {
const filePath = Utils.concatUrls(file.directory.path, file.directory.name, file.name);
const gpx = await this.networkService.getXML('/gallery/content/' + filePath);
const elements = gpx.getElementsByTagName('trkpt');
const points: MapPath[] = [];
for (let i = 0; i < elements.length; i++) {
points.push({
latitude: parseFloat(elements[i].getAttribute('lat')),
longitude: parseFloat(elements[i].getAttribute('lon'))
});
}
return points;
}
}
export interface MapPath {
latitude: number;
longitude: number;
}

View File

@ -1,5 +1,5 @@
import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Message} from '../../../../common/entities/Message';
import {SlimLoadingBarService} from 'ng2-slim-loading-bar';
import 'rxjs/Rx';
@ -33,6 +33,30 @@ export class NetworkService {
return url;
}
public getXML<T>(url: string): Promise<Document> {
this.slimLoadingBarService.visible = true;
this.slimLoadingBarService.start(() => {
this.slimLoadingBarService.visible = false;
});
const process = (res: string): Document => {
this.slimLoadingBarService.complete();
const parser = new DOMParser();
return parser.parseFromString(res, 'text/xml');
};
const err = (error) => {
this.slimLoadingBarService.complete();
return this.handleError(error);
};
return this._http.get(this._apiBaseUrl + url, {responseType: 'text'})
.toPromise()
.then(process)
.catch(err);
}
public postJson<T>(url: string, data: any = {}): Promise<T> {
return this.callJson('post', url, data);
}

View File

@ -11,6 +11,7 @@ import {Connection} from 'typeorm';
import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity';
import {Utils} from '../../../../../common/Utils';
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
import {FileDTO} from '../../../../../common/entities/FileDTO';
class GalleryManagerTest extends GalleryManager {
@ -71,9 +72,12 @@ describe('GalleryManager', () => {
delete dir.id;
dir.media.forEach((media: MediaDTO) => {
delete media.id;
});
if (dir.metaFile) {
dir.metaFile.forEach((file: FileDTO) => {
delete file.id;
});
}
if (dir.directories) {
dir.directories.forEach((directory: DirectoryDTO) => {
removeIds(directory);
@ -87,6 +91,7 @@ describe('GalleryManager', () => {
const parent = TestHelper.getRandomizedDirectoryEntry();
const p1 = TestHelper.getRandomizedPhotoEntry(parent, 'Photo1');
const p2 = TestHelper.getRandomizedPhotoEntry(parent, 'Photo2');
const gpx = TestHelper.getRandomizedGPXEntry(parent, 'GPX1');
const subDir = TestHelper.getRandomizedDirectoryEntry(parent, 'subDir');
const sp1 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto1');
const sp2 = TestHelper.getRandomizedPhotoEntry(subDir, 'subPhoto2');
@ -103,6 +108,7 @@ describe('GalleryManager', () => {
removeIds(selected);
subDir.isPartial = true;
delete subDir.directories;
delete subDir.metaFile;
expect(Utils.clone(selected)).to.deep.equal(Utils.clone(parent));
});

View File

@ -15,8 +15,6 @@ import {SearchManager} from '../../../../../backend/model/sql/SearchManager';
import {AutoCompleteItem, SearchTypes} from '../../../../../common/entities/AutoCompleteItem';
import {SearchResultDTO} from '../../../../../common/entities/SearchResultDTO';
import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity';
import {MediaDimensionEntity} from '../../../../../backend/model/sql/enitites/MediaEntity';
import {OrientationTypes} from 'ts-exif-parser';
import {Utils} from '../../../../../common/Utils';
import {TestHelper} from './TestHelper';
import {VideoEntity} from '../../../../../backend/model/sql/enitites/VideoEntity';
@ -116,7 +114,8 @@ describe('SearchManager', () => {
searchText: 'sw',
searchType: null,
directories: [],
media: [p, p2,v],
media: [p, p2, v],
metaFile: [],
resultOverflow: false
}));
@ -125,6 +124,7 @@ describe('SearchManager', () => {
searchType: SearchTypes.position,
directories: [],
media: [p],
metaFile: [],
resultOverflow: false
}));
@ -133,6 +133,7 @@ describe('SearchManager', () => {
searchType: SearchTypes.keyword,
directories: [],
media: [p2],
metaFile: [],
resultOverflow: false
}));
@ -141,6 +142,7 @@ describe('SearchManager', () => {
searchType: SearchTypes.keyword,
directories: [],
media: [p2],
metaFile: [],
resultOverflow: false
}));
@ -149,6 +151,7 @@ describe('SearchManager', () => {
searchType: SearchTypes.keyword,
directories: [dir],
media: [p, p2],
metaFile: [],
resultOverflow: false
}));
});
@ -160,7 +163,8 @@ describe('SearchManager', () => {
expect(Utils.clone(await sm.instantSearch('sw'))).to.deep.equal(Utils.clone({
searchText: 'sw',
directories: [],
media: [p, p2,v],
media: [p, p2, v],
metaFile: [],
resultOverflow: false
}));
@ -168,6 +172,7 @@ describe('SearchManager', () => {
searchText: 'Tatooine',
directories: [],
media: [p],
metaFile: [],
resultOverflow: false
}));
@ -175,6 +180,7 @@ describe('SearchManager', () => {
searchText: 'ortm',
directories: [],
media: [p2],
metaFile: [],
resultOverflow: false
}));
@ -182,6 +188,7 @@ describe('SearchManager', () => {
searchText: 'ortm',
directories: [],
media: [p2],
metaFile: [],
resultOverflow: false
}));
@ -189,6 +196,7 @@ describe('SearchManager', () => {
searchText: 'wa',
directories: [dir],
media: [p, p2],
metaFile: [],
resultOverflow: false
}));
});

View File

@ -10,6 +10,7 @@ import {OrientationTypes} from 'ts-exif-parser';
import {DirectoryEntity} from '../../../../../backend/model/sql/enitites/DirectoryEntity';
import {Utils} from '../../../../../common/Utils';
import {VideoEntity, VideoMetadataEntity} from '../../../../../backend/model/sql/enitites/VideoEntity';
import {FileEntity} from '../../../../../backend/model/sql/enitites/FileEntity';
export class TestHelper {
@ -126,6 +127,7 @@ export class TestHelper {
parent.directories.push(dir);
}
dir.directories = [];
dir.metaFile = [];
dir.media = [];
dir.lastModified = Date.now();
dir.lastScanned = null;
@ -133,6 +135,16 @@ export class TestHelper {
return dir;
}
public static getRandomizedGPXEntry(dir: DirectoryEntity, forceStr = null): FileEntity {
const d = new FileEntity();
d.name = forceStr + '_' + Math.random().toString(36).substring(7) + '.gpx';
d.directory = dir;
dir.metaFile.push(d);
return d;
}
public static getRandomizedPhotoEntry(dir: DirectoryEntity, forceStr = null) {