1
0
mirror of https://github.com/bpatrik/pigallery2.git synced 2025-09-16 09:16:27 +02:00

replacing google maps with open street maps

This commit is contained in:
Patrik J. Braun
2018-12-07 22:06:13 +01:00
parent e4214c65e8
commit b27365bbad
25 changed files with 254 additions and 256 deletions

View File

@@ -1,9 +1,8 @@
# User rights
| id | Role | rights |
|----|---------------|-------------|
| 1 | Limited Guest | list dir |
| 2 | Guest | +search |
| 3 | User | +share |
| 4 | Admin | +settings |
| 5 | Developer | +see errors |
| id | Role | rights | who has it |
|----|---------------|----------------------|------------|
| 1 | Limited Guest | listing directory | using shared link |
| 2 | Guest | + search | one one (you can set manually in the db, if necessary) |
| 3 | User | + share | default role |
| 4 | Admin | + settings | dDefault (pregenerated) user (also the default right if authentication is off) |
| 5 | Developer | + see errors | one one (you can set manually in the db, if necessary) |

View File

@@ -17,9 +17,15 @@
"tsConfig": "frontend/tsconfig.app.json",
"polyfills": "frontend/polyfills.ts",
"assets": [
{
"glob": "**/*",
"input": "./node_modules/leaflet/dist/images",
"output": "/"
},
"frontend/assets"
],
"styles": [
"node_modules/leaflet/dist/leaflet.css",
"node_modules/ngx-toastr/toastr.css",
"node_modules/bootstrap/dist/css/bootstrap.css",
"node_modules/open-iconic/font/css/open-iconic-bootstrap.css",

View File

@@ -95,7 +95,6 @@ export class AuthenticationMWs {
sharingKey: req.query[QueryParams.gallery.sharingKey_short] || req.params[QueryParams.gallery.sharingKey_long]
});
console.log(sharing);
if (!sharing || sharing.expires < Date.now() ||
(Config.Client.Sharing.passwordProtected === true
&& (sharing.password)

View File

@@ -12,8 +12,8 @@ import {ProjectPath} from '../../ProjectPath';
import {SQLConnection} from '../sql/SQLConnection';
import * as fs from 'fs';
import {ClientConfig} from '../../../common/config/public/ConfigClass';
import VideoConfig = ClientConfig.VideoConfig;
import {FFmpegFactory} from '../FFmpegFactory';
import VideoConfig = ClientConfig.VideoConfig;
import MetaFileConfig = ClientConfig.MetaFileConfig;
const LOG_TAG = '[ConfigDiagnostics]';
@@ -155,8 +155,9 @@ export class ConfigDiagnostics {
static async testMapConfig(map: ClientConfig.MapConfig) {
if (map.enabled === true && (!map.googleApiKey || map.googleApiKey.length === 0)) {
throw new Error('Maps need a valid google api key');
if (map.enabled === true && map.mapProvider === ClientConfig.MapProviders.Custom &&
(!map.tileUrl || map.tileUrl.length === 0)) {
throw new Error('Custom maps need a valid tile url');
}
}
@@ -270,11 +271,11 @@ export class ConfigDiagnostics {
await ConfigDiagnostics.testMapConfig(Config.Client.Map);
} catch (ex) {
const err: Error = ex;
NotificationManager.warning('Maps is not supported with these settings. Disabling temporally. ' +
NotificationManager.warning('Maps is not supported with these settings. Using open street maps temporally. ' +
'Please adjust the config properly.', err.toString());
Logger.warn(LOG_TAG, 'Maps is not supported with these settings. Disabling temporally. ' +
Logger.warn(LOG_TAG, 'Maps is not supported with these settings. Using open street maps temporally ' +
'Please adjust the config properly.', err.toString());
Config.Client.Map.enabled = false;
Config.Client.Map.mapProvider = ClientConfig.MapProviders.OpenStreetMap;
}
}

View File

@@ -7,6 +7,12 @@ export class Utils {
return R;
}
static wait(time: number) {
return new Promise((resolve) => {
setTimeout(resolve, time);
});
}
static removeNullOrEmptyObj(obj: any) {
if (typeof obj !== 'object' || obj == null) {

View File

@@ -2,6 +2,11 @@ import {SortingMethods} from '../../entities/SortingMethods';
import {UserRoles} from '../../entities/UserDTO';
export module ClientConfig {
export enum MapProviders {
OpenStreetMap, Custom
}
export interface SearchConfig {
enabled: boolean;
instantSearchEnabled: boolean;
@@ -23,7 +28,8 @@ export module ClientConfig {
export interface MapConfig {
enabled: boolean;
googleApiKey: string;
mapProvider: MapProviders;
tileUrl: string;
}
export interface ThumbnailConfig {
@@ -100,7 +106,8 @@ export class PublicConfigClass {
},
Map: {
enabled: true,
googleApiKey: ''
mapProvider: ClientConfig.MapProviders.OpenStreetMap,
tileUrl: ''
},
RandomPhoto: {
enabled: true

View File

@@ -8,7 +8,6 @@ import {
} from '@angular/core';
import {BrowserModule, HAMMER_GESTURE_CONFIG, HammerGestureConfig} from '@angular/platform-browser';
import {FormsModule} from '@angular/forms';
import {AgmCoreModule} from '@agm/core';
import {AppComponent} from './app.component';
import {appRoutes} from './app.routing';
import {UserService} from './model/network/user.service';
@@ -20,6 +19,7 @@ import {FullScreenService} from './gallery/fullscreen.service';
import {AuthenticationService} from './model/network/authentication.service';
import {UserMangerSettingsComponent} from './settings/usermanager/usermanager.settings.component';
import {FrameComponent} from './frame/frame.component';
import {YagaModule} from '@yaga/leaflet-ng2';
import {GalleryLightboxMediaComponent} from './gallery/lightbox/media/media.lightbox.gallery.component';
import {GalleryPhotoLoadingComponent} from './gallery/grid/photo/loading/loading.photo.grid.gallery.component';
import {GalleryNavigatorComponent} from './gallery/navigator/navigator.gallery.component';
@@ -36,8 +36,6 @@ import {GalleryMapComponent} from './gallery/map/map.gallery.component';
import {GalleryMapLightboxComponent} from './gallery/map/lightbox/lightbox.map.gallery.component';
import {ThumbnailManagerService} from './gallery/thumnailManager.service';
import {OverlayService} from './gallery/overlay.service';
import {Config} from '../../common/config/public/Config';
import {LAZY_MAPS_API_CONFIG} from '@agm/core/services';
import {SlimLoadingBarModule} from 'ng2-slim-loading-bar';
import {GalleryShareComponent} from './gallery/share/share.gallery.component';
import {ShareLoginComponent} from './sharelogin/share-login.component';
@@ -78,14 +76,6 @@ import {DurationPipe} from './pipes/DurationPipe';
import {MapService} from './gallery/map/map.service';
import {MetaFileSettingsComponent} from './settings/metafiles/metafile.settings.component';
@Injectable()
export class GoogleMapsConfig {
apiKey: string;
constructor() {
this.apiKey = Config.Client.Map.googleApiKey;
}
}
@Injectable()
export class MyHammerConfig extends HammerGestureConfig {
@@ -131,9 +121,9 @@ export function translationsFactory(locale: string) {
ModalModule.forRoot(),
CollapseModule.forRoot(),
BsDropdownModule.forRoot(),
AgmCoreModule.forRoot(),
SlimLoadingBarModule.forRoot(),
BsDatepickerModule.forRoot()
BsDatepickerModule.forRoot(),
YagaModule
],
declarations: [AppComponent,
LoginComponent,
@@ -179,7 +169,6 @@ export function translationsFactory(locale: string) {
],
providers: [
{provide: UrlSerializer, useClass: CustomUrlSerializer},
{provide: LAZY_MAPS_API_CONFIG, useClass: GoogleMapsConfig},
{provide: HAMMER_GESTURE_CONFIG, useClass: MyHammerConfig},
NetworkService,
ShareService,

View File

@@ -1,7 +1,7 @@
.content {
background-color: #F7F7F7;
height: 100%;
overflow-y: scroll;
overflow-y: auto;
}
.row {
@@ -30,7 +30,7 @@
padding-right: 5px;
}
.sebm-google-map-container {
.yaga-map {
width: 100%;
height: 100%;
}
@@ -45,9 +45,14 @@
font-size: 1.2rem;
}
.dir-link{
.dir-link {
cursor: pointer;
}
.dir-link:hover{
.dir-link:hover {
text-decoration: underline;
}
.modal-header {
padding: 0.4rem 1rem;
}

View File

@@ -29,7 +29,7 @@
</div>
<div class="col-10">
<div class="details-main">
{{ media.metadata.creationDate | date: (isThisYear() ? 'MMMM d': 'longDate')}}
{{ media.metadata.creationDate | date: (isThisYear() ? 'MMMM d' : 'longDate')}}
</div>
<div class="details-sub row">
<div class="col-12">{{ media.metadata.creationDate | date :'EEEE'}}, {{getTime()}}</div>
@@ -47,8 +47,13 @@
{{"Video"}}
</div>
<div class="details-sub row">
<div class="col-6" *ngIf="VideoData.duration"><ng-container i18n>duration</ng-container>: {{VideoData.duration | duration}}</div>
<div class="col-6" *ngIf="VideoData.bitRate"><ng-container i18n>bit rate</ng-container>: {{calcSize(VideoData.bitRate)}}/s</div>
<div class="col-6" *ngIf="VideoData.duration">
<ng-container i18n>duration</ng-container>
: {{VideoData.duration | duration}}</div>
<div class="col-6" *ngIf="VideoData.bitRate">
<ng-container i18n>bit rate</ng-container>
: {{calcSize(VideoData.bitRate)}}/s
</div>
</div>
</div>
</div>
@@ -93,17 +98,14 @@
</div>
<div id="map" *ngIf="hasGPS() && mapEnabled">
<agm-map
[disableDefaultUI]="true"
[zoomControl]="false"
[streetViewControl]="false"
[zoom]="10"
[latitude]="PositionData.GPSData.latitude"
[longitude]="PositionData.GPSData.longitude">
<agm-marker
[latitude]="PositionData.GPSData.latitude"
[longitude]="PositionData.GPSData.longitude">
</agm-marker>
</agm-map>
<yaga-map [zoom]="10"
[lat]="PositionData.GPSData.latitude"
[lng]="PositionData.GPSData.longitude">
<yaga-marker
[lat]="PositionData.GPSData.latitude"
[lng]="PositionData.GPSData.longitude">
</yaga-marker>
<yaga-tile-layer [url]="mapService.MapLayer"></yaga-tile-layer>
</yaga-map>
</div>
</div>

View File

@@ -1,10 +1,11 @@
import {Component, ElementRef, EventEmitter, Input, Output} from '@angular/core';
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {CameraMetadata, PhotoDTO, PositionMetaData} from '../../../../../common/entities/PhotoDTO';
import {Config} from '../../../../../common/config/public/Config';
import {MediaDTO} from '../../../../../common/entities/MediaDTO';
import {VideoDTO, VideoMetadata} from '../../../../../common/entities/VideoDTO';
import {Utils} from '../../../../../common/Utils';
import {QueryService} from '../../../model/query.service';
import {MapService} from '../../map/map.service';
@Component({
selector: 'app-info-panel',
@@ -17,7 +18,8 @@ export class InfoPanelLightboxComponent {
public mapEnabled = true;
constructor(public queryService: QueryService) {
constructor(public queryService: QueryService,
public mapService: MapService) {
this.mapEnabled = Config.Client.Map.enabled;
}
@@ -38,7 +40,6 @@ export class InfoPanelLightboxComponent {
}
calcSize(size: number) {
const postFixes = ['B', 'KB', 'MB', 'GB', 'TB'];
let index = 0;

View File

@@ -83,3 +83,4 @@
top: calc(50% - 25px);
left: calc(50% - 25px);
}

View File

@@ -6,64 +6,50 @@
[style.top.px]="lightboxDimension.top"
[style.left.px]="lightboxDimension.left"
[style.opacity]="opacity">
<agm-map
#map
[style.width.px]="mapDimension.width"
[style.height.px]="mapDimension.height"
[fitBounds]="true">
<ng-container *ngIf="map.zoom > 11">
<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>
</ng-container>
<ng-container *ngIf="map.zoom <= 11">
<agm-polyline *ngFor="let path of pathOutlines"
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>
</ng-container>
<agm-marker
<yaga-map #yagaMap
[style.width.px]="mapDimension.width"
[style.height.px]="mapDimension.height">
<yaga-polyline *ngFor="let path of paths"
[latLngs]="path">
</yaga-polyline>
<yaga-marker
*ngFor="let path of paths"
[latitude]="path[0].latitude"
[longitude]="path[0].longitude"
iconUrl="https://cdn.mapmarker.io/api/v1/fa?size=32&icon=fa-map-marker-alt&color=%23006fe6"
[agmFitBounds]="true">
</agm-marker>
<agm-marker
[lat]="path[0].lat"
[lng]="path[1].lng">
</yaga-marker>
<yaga-marker
*ngFor="let photo of mapPhotos"
[latitude]="photo.latitude"
[longitude]="photo.longitude"
[iconUrl]="photo.iconUrl | fixOrientation:photo.orientation | async"
(markerClick)="loadPreview(photo)"
[agmFitBounds]="true">
<agm-info-window>
[lat]="photo.lat"
[lng]="photo.lng">
<yaga-icon
*ngIf="photo.iconUrl"
[iconUrl]="photo.iconUrl"
[iconSize]="iconSize"
></yaga-icon>
<yaga-popup
(open)="loadPreview(photo)"
[minWidth]="photo.preview.width">
<img *ngIf="photo.preview.thumbnail.Src"
[style.width.px]="photo.preview.width"
[style.height.px]="photo.preview.height"
[src]="photo.preview.thumbnail.Src | fixOrientation:photo.orientation | async">
<div class="preview-loading"
*ngIf="!photo.preview.thumbnail.Src"
[style.width.px]="photo.preview.width"
[style.height.px]="photo.preview.height"
*ngIf="!photo.preview.thumbnail.Src">
[style.height.px]="photo.preview.height">
<span class="oi"
[ngClass]="photo.preview.thumbnail.Error ? 'oi-warning' : 'oi-picture'"
aria-hidden="true">
</span>
</div>
</agm-info-window>
</agm-marker>
</agm-map>
</yaga-popup>
</yaga-marker>
<yaga-attribution-control
[attributions]="mapService.Attributions"
></yaga-attribution-control>
<yaga-tile-layer [url]="mapService.MapLayer"></yaga-tile-layer>
</yaga-map>
</div>

View File

@@ -2,7 +2,6 @@ import {Component, ElementRef, HostListener, Input, OnChanges, ViewChild, AfterV
import {PhotoDTO} from '../../../../../common/entities/PhotoDTO';
import {Dimension} from '../../../model/IRenderable';
import {FullScreenService} from '../../fullscreen.service';
import {AgmMap, LatLngBounds, MapsAPILoader} from '@agm/core';
import {IconThumbnail, Thumbnail, ThumbnailManagerService} from '../../thumnailManager.service';
import {MediaIcon} from '../../MediaIcon';
import {Media} from '../../Media';
@@ -10,11 +9,12 @@ 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';
import {MapService} from '../map.service';
import {LatLng, Point} from 'leaflet';
import {MapComponent} from '@yaga/leaflet-ng2';
import {FixOrientationPipe} from '../../FixOrientationPipe';
@Component({
selector: 'app-gallery-map-lightbox',
@@ -32,19 +32,16 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
public controllersVisible = false;
public opacity = 1.0;
mapPhotos: MapPhoto[] = [];
paths: MapPath[][] = [];
pathOutlines: MapPath[][] = [];
mapCenter = {latitude: 0, longitude: 0};
paths: LatLng[][] = [];
@ViewChild('root') elementRef: ElementRef;
@ViewChild('yagaMap') yagaMap: MapComponent;
@ViewChild(AgmMap) map: AgmMap;
public iconSize = new Point(Config.Client.Thumbnail.iconSize, Config.Client.Thumbnail.iconSize);
constructor(public fullScreenService: FullScreenService,
private thumbnailService: ThumbnailManagerService,
private mapService: MapService,
private mapsAPILoader: MapsAPILoader) {
public mapService: MapService) {
}
ngOnChanges() {
@@ -58,7 +55,8 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
}
public show(position: Dimension) {
public async show(position: Dimension) {
this.hideImages();
this.visible = true;
this.opacity = 1.0;
@@ -71,21 +69,20 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
width: this.getScreenWidth(),
height: this.getScreenHeight()
};
this.map.triggerResize().then(() => {
this.controllersVisible = true;
});
this.showImages();
this.centerMap();
PageHelper.hideScrollY();
setTimeout(() => {
this.lightboxDimension = <Dimension>{
top: 0,
left: 0,
width: this.getScreenWidth(),
height: this.getScreenHeight()
};
this.showImages();
}, 0);
await Utils.wait(0);
this.lightboxDimension = <Dimension>{
top: 0,
left: 0,
width: this.getScreenWidth(),
height: this.getScreenHeight()
};
await Utils.wait(350);
this.yagaMap.invalidateSize();
this.centerMap();
this.controllersVisible = true;
}
public hide() {
@@ -105,6 +102,7 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
setTimeout(() => {
this.visible = false;
this.hideImages();
this.yagaMap.zoom = 2;
}, 500);
}
@@ -127,8 +125,8 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
const iconTh = this.thumbnailService.getIcon(new MediaIcon(p));
iconTh.Visible = true;
const obj: MapPhoto = {
latitude: p.metadata.positionData.GPSData.latitude,
longitude: p.metadata.positionData.GPSData.longitude,
lat: p.metadata.positionData.GPSData.latitude,
lng: p.metadata.positionData.GPSData.longitude,
iconThumbnail: iconTh,
orientation: p.metadata.orientation,
preview: {
@@ -139,37 +137,31 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
};
if (iconTh.Available === true) {
obj.iconUrl = iconTh.Src;
FixOrientationPipe.transform(iconTh.Src, p.metadata.orientation).then((icon) => {
obj.iconUrl = icon;
});
} else {
iconTh.OnLoad = () => {
obj.iconUrl = iconTh.Src;
FixOrientationPipe.transform(iconTh.Src, p.metadata.orientation).then((icon) => {
obj.iconUrl = icon;
});
};
}
return obj;
});
if (this.gpxFiles) {
this.loadGPXFiles().catch(console.error);
}
}
private gpxFilter(list: MapPath[]) {
let last = list[0];
const out = [];
for (let i = 1; i < list.length; i++) {
if (this.mapService.calcDistance(list[i], last) > 0.5) {
out.push(list[i]);
last = list[i];
}
private centerMap() {
if (this.mapPhotos.length > 0) {
this.yagaMap.fitBounds(<any>this.mapPhotos);
}
if (out.length < 2) {
out.push(list[list.length - 1]);
}
return out;
}
private async loadGPXFiles(): Promise<void> {
this.paths = [];
for (let i = 0; i < this.gpxFiles.length; i++) {
@@ -181,8 +173,7 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
if (path.length === 0) {
continue;
}
this.paths.push(path);
this.pathOutlines.push(this.gpxFilter(path));
this.paths.push(<LatLng[]>path);
}
}
@@ -193,7 +184,6 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
}
hideImages() {
this.mapCenter = {longitude: 0, latitude: 0};
this.mapPhotos.forEach((mp) => {
mp.iconThumbnail.destroy();
mp.preview.thumbnail.destroy();
@@ -228,8 +218,8 @@ export class GalleryMapLightboxComponent implements OnChanges, AfterViewInit {
}
export interface MapPhoto {
latitude: number;
longitude: number;
lat: number;
lng: number;
iconUrl?: string;
iconThumbnail: IconThumbnail;
orientation: OrientationTypes;

View File

@@ -1,4 +1,4 @@
.sebm-google-map-container {
.yaga-map{
width: 100%;
height: 100%;
}

View File

@@ -1,21 +1,23 @@
<ng-template [ngIf]="mapPhotos.length>0">
<app-gallery-map-lightbox [photos]="photos" [gpxFiles]="metaFiles"></app-gallery-map-lightbox>
<div id="map" #map>
<agm-map
[disableDefaultUI]="true"
[zoomControl]="false"
[streetViewControl]="false"
[usePanning]="false"
[draggable]="false"
[zoom]="0"
[fitBounds]="true">
<agm-marker
<yaga-map #yagaMap
[draggingEnabled]="false"
[keyboardEnabled]="false"
[tapEnabled]="false"
[boxZoomEnabled]="false"
[doubleClickZoomEnabled]="false">
<yaga-marker
*ngFor="let photo of mapPhotos"
[latitude]="photo.latitude"
[longitude]="photo.longitude"
[agmFitBounds]="true">
</agm-marker>
</agm-map>
[lat]="photo.lat"
[lng]="photo.lng">
</yaga-marker>
<yaga-attribution-control
[attributions]="mapService.Attributions"
></yaga-attribution-control>
<yaga-tile-layer [url]="mapService.MapLayer"></yaga-tile-layer>
</yaga-map>
<div class="overlay" (click)="click()"
[style.margin-top.px]="-height"
[style.height.px]="height">

View File

@@ -2,10 +2,9 @@ import {Component, ElementRef, Input, OnChanges, ViewChild, AfterViewInit} from
import {PhotoDTO} from '../../../../common/entities/PhotoDTO';
import {Dimension, IRenderable} from '../../model/IRenderable';
import {GalleryMapLightboxComponent} from './lightbox/lightbox.map.gallery.component';
import {ThumbnailManagerService} from '../thumnailManager.service';
import {FullScreenService} from '../fullscreen.service';
import {LatLngBounds, MapsAPILoader, AgmMap} from '@agm/core';
import {FileDTO} from '../../../../common/entities/FileDTO';
import {MapService} from './map.service';
import {MapComponent} from '@yaga/leaflet-ng2';
@Component({
selector: 'app-gallery-map',
@@ -18,12 +17,13 @@ export class GalleryMapComponent implements OnChanges, IRenderable, AfterViewIni
@Input() metaFiles: FileDTO[];
@ViewChild(GalleryMapLightboxComponent) mapLightbox: GalleryMapLightboxComponent;
mapPhotos: Array<{ latitude: number, longitude: number }> = [];
mapPhotos: Array<{ lat: number, lng: number }> = [];
@ViewChild('map') mapElement: ElementRef;
@ViewChild('yagaMap') yagaMap: MapComponent;
height: number = null;
constructor(private mapsAPILoader: MapsAPILoader) {
constructor(public mapService: MapService) {
}
ngOnChanges() {
@@ -32,17 +32,25 @@ export class GalleryMapComponent implements OnChanges, IRenderable, AfterViewIni
p.metadata.positionData.GPSData.latitude && p.metadata.positionData.GPSData.longitude;
}).map(p => {
return {
latitude: p.metadata.positionData.GPSData.latitude,
longitude: p.metadata.positionData.GPSData.longitude
lat: p.metadata.positionData.GPSData.latitude,
lng: p.metadata.positionData.GPSData.longitude
};
});
if (this.yagaMap) {
this.yagaMap.setView(this.mapPhotos[0], 0);
this.yagaMap.fitBounds(<any>this.mapPhotos);
this.yagaMap.zoom = 0;
}
}
ngAfterViewInit() {
setTimeout(() => {
this.height = this.mapElement.nativeElement.clientHeight;
this.yagaMap.setView(this.mapPhotos[0], 0);
this.yagaMap.fitBounds(<any>this.mapPhotos);
this.yagaMap.zoom = 0;
}, 0);
}

View File

@@ -2,6 +2,9 @@ import {Injectable} from '@angular/core';
import {NetworkService} from '../../model/network/network.service';
import {FileDTO} from '../../../../common/entities/FileDTO';
import {Utils} from '../../../../common/Utils';
import {OSM_TILE_LAYER_URL} from '@yaga/leaflet-ng2';
import {Config} from '../../../../common/config/public/Config';
import {ClientConfig} from '../../../../common/config/public/ConfigClass';
@Injectable()
export class MapService {
@@ -11,21 +14,6 @@ export class MapService {
}
public calcDistance(loc: MapPath, loc2: MapPath): number {
const radlat1 = Math.PI * loc.latitude / 180;
const radlat2 = Math.PI * loc2.latitude / 180;
const theta = loc.longitude - loc2.longitude;
const radtheta = Math.PI * theta / 180;
let dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
if (dist > 1) {
dist = 1;
}
dist = Math.acos(dist);
dist = dist * 180 / Math.PI;
dist = dist * 60 * 1.1515;
return dist * 1.609344;
}
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);
@@ -33,17 +21,29 @@ export class MapService {
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'))
lat: parseFloat(elements[i].getAttribute('lat')),
lng: parseFloat(elements[i].getAttribute('lon'))
});
}
return points;
}
public get Attributions(): string[] {
return ['&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'];
}
public get MapLayer(): string {
if (Config.Client.Map.mapProvider === ClientConfig.MapProviders.Custom) {
return Config.Client.Map.tileUrl;
}
return OSM_TILE_LAYER_URL;
}
}
export interface MapPath {
latitude: number;
longitude: number;
lat: number;
lng: number;
}

View File

@@ -17,7 +17,7 @@ import {I18n} from '@ngx-translate/i18n-polyfill';
})
export class DatabaseSettingsComponent extends SettingsComponent<DataBaseConfig> implements OnInit {
public types: Array<any> = [];
public types: { key: number, value: string }[] = [];
public DatabaseType: any;
constructor(_authService: AuthenticationService,
@@ -30,8 +30,7 @@ export class DatabaseSettingsComponent extends SettingsComponent<DataBaseConfig>
ngOnInit() {
super.ngOnInit();
this.types = Utils
.enumToArray(DatabaseType);
this.types = Utils.enumToArray(DatabaseType);
this.DatabaseType = DatabaseType;
}

View File

@@ -22,17 +22,25 @@
<div class="form-group row">
<label class="col-md-2 control-label" for="googleApiKey" i18n>Google maps api key</label>
<label class="col-md-2 control-label" for="mapProvider" i18n>Map provider</label>
<div class="col-md-10">
<input type="text" class="form-control" placeholder="Google api key"
[(ngModel)]="settings.googleApiKey"
[disabled]="!settings.enabled"
name="googleApiKey" id="googleApiKey" required>
<select name="mapProvider" id="mapProvider"
[disabled]="!settings.enabled"
class="form-control" [(ngModel)]="settings.mapProvider" required>
<option *ngFor="let type of mapProviders" [ngValue]="type.key">{{type.value}}
</option>
</select>
</div>
</div>
<div class="form-group row" *ngIf="settings.mapProvider === MapProviders.Custom">
<label class="col-md-2 control-label" for="tileUrl" i18n>Map tile url</label>
<div class="col-md-10">
<input type="text" class="form-control" placeholder="http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
[(ngModel)]="settings.tileUrl"
name="tileUrl" id="tileUrl" required>
<small class="form-text text-muted">
<ng-container i18n>To show the images on a map,</ng-container>&nbsp;
<a href="https://developers.google.com/maps/documentation/javascript/get-api-key"
i18n>google api key</a>&nbsp;
<ng-container i18n>is need.</ng-container>
<ng-container i18n>The map module will use this url to fetch the map tiles.</ng-container>
</small>
</div>
</div>

View File

@@ -6,6 +6,7 @@ import {NavigationService} from '../../model/navigation.service';
import {NotificationService} from '../../model/notification.service';
import {ClientConfig} from '../../../../common/config/public/ConfigClass';
import {I18n} from '@ngx-translate/i18n-polyfill';
import {Utils} from '../../../../common/Utils';
@Component({
@@ -17,12 +18,17 @@ import {I18n} from '@ngx-translate/i18n-polyfill';
})
export class MapSettingsComponent extends SettingsComponent<ClientConfig.MapConfig> {
public mapProviders: { key: number, value: string }[] = [];
public MapProviders = ClientConfig.MapProviders;
constructor(_authService: AuthenticationService,
_navigation: NavigationService,
_settingsService: MapSettingsService,
notification: NotificationService,
i18n: I18n) {
super(i18n('Map'), _authService, _navigation, <any>_settingsService, notification, i18n, s => s.Client.Map);
this.mapProviders = Utils.enumToArray(ClientConfig.MapProviders);
}

View File

@@ -4,6 +4,7 @@ import {DatabaseType, IPrivateConfig, ReIndexingSensitivity, ThumbnailProcessing
import {NetworkService} from '../model/network/network.service';
import {SortingMethods} from '../../../common/entities/SortingMethods';
import {UserRoles} from '../../../common/entities/UserDTO';
import {ClientConfig} from '../../../common/config/public/ConfigClass';
@Injectable()
export class SettingsService {
@@ -32,7 +33,8 @@ export class SettingsService {
},
Map: {
enabled: true,
googleApiKey: ''
mapProvider: ClientConfig.MapProviders.OpenStreetMap,
tileUrl: ''
},
RandomPhoto: {
enabled: true

View File

@@ -18,18 +18,15 @@
<body style="overflow-y: scroll; padding-right: 0 !important;">
<app-pi-gallery2>
<app-pi-gallery2>
<div style="position: absolute;
<div style="position: absolute;
top: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
left: 50%;
text-align: center">
<img src="assets/icon.png" style="max-width: 256px"/>
<h2>Loading...</h2>
</div>
</app-pi-gallery2>
<img src="assets/icon.png" style="max-width: 256px"/>
<h2>Loading...</h2>
</div>
</app-pi-gallery2>
</body>
</html>

View File

@@ -343,7 +343,7 @@
<source>duration</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.html</context>
<context context-type="linenumber">50</context>
<context context-type="linenumber">51</context>
</context-group>
<target>duration</target>
</trans-unit>
@@ -351,7 +351,7 @@
<source>bit rate</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.html</context>
<context context-type="linenumber">51</context>
<context context-type="linenumber">54</context>
</context-group>
<target>bit rate</target>
</trans-unit>
@@ -580,44 +580,36 @@
</context-group>
<target>Map settings</target>
</trans-unit>
<trans-unit id="2ac5d327999abb61d7353f475edffa8b1f0a8ad7" datatype="html">
<source>Google maps api key</source>
<trans-unit id="1bd9d57dffd8f2e6ed1c65e3ed7bf329f317e752" datatype="html">
<source>Map provider</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">25</context>
</context-group>
<target>Google maps api key</target>
<target>Map provider</target>
</trans-unit>
<trans-unit id="83d20bb14a5d264b30b919fd3b52903f0b7a124c" datatype="html">
<source>To show the images on a map,</source>
<trans-unit id="559b1ca26c5fffeb5c5d4fbc71d64b85824d9188" datatype="html">
<source>Map tile url</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">32</context>
<context context-type="linenumber">37</context>
</context-group>
<target>To show the images on a map,</target>
<target>Map tile url</target>
</trans-unit>
<trans-unit id="9b480df2a8ef25163f0c093fe11c336908c7b55c" datatype="html">
<source>google api key</source>
<trans-unit id="853c11ccf6fba4454bdfb48dc708159fb7d11075" datatype="html">
<source>The map module will use this url to fetch the map tiles.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">34</context>
<context context-type="linenumber">43</context>
</context-group>
<target>google api key</target>
</trans-unit>
<trans-unit id="86a1216cdfe7002796280c5541f0b9f765efae78" datatype="html">
<source>is need.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">35</context>
</context-group>
<target>is need.</target>
<target>The map module will use this url to fetch the map tiles.</target>
</trans-unit>
<trans-unit id="d682be8fc94c1861394919e021e9dcf8def8f554" datatype="html">
<source>Save
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">50</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
@@ -658,7 +650,7 @@
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">45</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>

View File

@@ -343,7 +343,7 @@
<source>duration</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.html</context>
<context context-type="linenumber">50</context>
<context context-type="linenumber">51</context>
</context-group>
<target>hossz</target>
</trans-unit>
@@ -351,7 +351,7 @@
<source>bit rate</source>
<context-group purpose="location">
<context context-type="sourcefile">app/gallery/lightbox/infopanel/info-panel.lightbox.gallery.component.html</context>
<context context-type="linenumber">51</context>
<context context-type="linenumber">54</context>
</context-group>
<target>bit ráta</target>
</trans-unit>
@@ -580,44 +580,36 @@
</context-group>
<target>Térképbeállítások</target>
</trans-unit>
<trans-unit id="2ac5d327999abb61d7353f475edffa8b1f0a8ad7" datatype="html">
<source>Google maps api key</source>
<trans-unit id="1bd9d57dffd8f2e6ed1c65e3ed7bf329f317e752" datatype="html">
<source>Map provider</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">25</context>
</context-group>
<target>Google maps api kulcs</target>
<target>Térképszolgáltató</target>
</trans-unit>
<trans-unit id="83d20bb14a5d264b30b919fd3b52903f0b7a124c" datatype="html">
<source>To show the images on a map,</source>
<trans-unit id="559b1ca26c5fffeb5c5d4fbc71d64b85824d9188" datatype="html">
<source>Map tile url</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">32</context>
<context context-type="linenumber">37</context>
</context-group>
<target>Ahhoz, hogy megjelenjenek a képet a térképen,</target>
<target>Térképes csempe url</target>
</trans-unit>
<trans-unit id="9b480df2a8ef25163f0c093fe11c336908c7b55c" datatype="html">
<source>google api key</source>
<trans-unit id="853c11ccf6fba4454bdfb48dc708159fb7d11075" datatype="html">
<source>The map module will use this url to fetch the map tiles.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">34</context>
<context context-type="linenumber">43</context>
</context-group>
<target>google api kulcsra</target>
</trans-unit>
<trans-unit id="86a1216cdfe7002796280c5541f0b9f765efae78" datatype="html">
<source>is need.</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">35</context>
</context-group>
<target>szükség van.</target>
<target>A térkép modul ezt az URL-t fogja használni a térkép letöltéséhez.</target>
</trans-unit>
<trans-unit id="d682be8fc94c1861394919e021e9dcf8def8f554" datatype="html">
<source>Save
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">50</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>
@@ -658,7 +650,7 @@
</source>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/map/map.settings.component.html</context>
<context context-type="linenumber">45</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">app/settings/thumbnail/thumbanil.settings.component.html</context>

View File

@@ -46,7 +46,6 @@
"winston": "2.4.2"
},
"devDependencies": {
"@agm/core": "1.0.0-beta.5",
"@angular-devkit/build-angular": "0.11.0",
"@angular-devkit/build-optimizer": "0.11.0",
"@angular/animations": "7.1.1",
@@ -74,6 +73,7 @@
"@types/node": "10.12.11",
"@types/sharp": "0.21.0",
"@types/winston": "2.3.9",
"@yaga/leaflet-ng2": "^1.0.0",
"bootstrap": "4.1.3",
"chai": "4.2.0",
"codelyzer": "4.5.0",
@@ -95,7 +95,7 @@
"karma-jasmine": "2.0.1",
"karma-jasmine-html-reporter": "1.4.0",
"karma-remap-istanbul": "0.6.0",
"karma-systemjs": "0.16.0",
"karma-systemjs": "0.16.0",
"merge2": "1.2.3",
"mocha": "5.2.0",
"ng2-cookies": "1.0.12",