mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
implementibg basic google maps function
This commit is contained in:
parent
ba4cad7bef
commit
f1a43c9f92
@ -18,7 +18,7 @@ const Pool = require('threads').Pool;
|
|||||||
const pool = new Pool(Config.Client.concurrentThumbnailGenerations);
|
const pool = new Pool(Config.Client.concurrentThumbnailGenerations);
|
||||||
|
|
||||||
pool.run(
|
pool.run(
|
||||||
(input: {imagePath: string, size: number, thPath: string}, done) => {
|
(input: {imagePath: string, size: number, makeSquare: boolean, thPath: string}, done) => {
|
||||||
|
|
||||||
//generate thumbnail
|
//generate thumbnail
|
||||||
let Jimp = require("jimp");
|
let Jimp = require("jimp");
|
||||||
@ -32,11 +32,16 @@ pool.run(
|
|||||||
*
|
*
|
||||||
* @type {number}
|
* @type {number}
|
||||||
*/
|
*/
|
||||||
let ratio = image.bitmap.height / image.bitmap.width;
|
if (input.makeSquare == false) {
|
||||||
let newWidth = Math.sqrt((input.size * input.size) / ratio);
|
let ratio = image.bitmap.height / image.bitmap.width;
|
||||||
|
let newWidth = Math.sqrt((input.size * input.size) / ratio);
|
||||||
image.resize(newWidth, Jimp.AUTO, Jimp.RESIZE_BEZIER);
|
|
||||||
|
|
||||||
|
image.resize(newWidth, Jimp.AUTO, Jimp.RESIZE_BEZIER);
|
||||||
|
} else {
|
||||||
|
let ratio = image.bitmap.height / image.bitmap.width;
|
||||||
|
image.resize(input.size / Math.min(ratio, 1), Jimp.AUTO, Jimp.RESIZE_BEZIER);
|
||||||
|
image.crop(0, 0, input.size, input.size);
|
||||||
|
}
|
||||||
image.quality(60); // set JPEG quality
|
image.quality(60); // set JPEG quality
|
||||||
image.write(input.thPath, () => { // save
|
image.write(input.thPath, () => { // save
|
||||||
return done();
|
return done();
|
||||||
@ -113,6 +118,25 @@ export class ThumbnailGeneratorMWs {
|
|||||||
size = Config.Client.thumbnailSizes[0];
|
size = Config.Client.thumbnailSizes[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThumbnailGeneratorMWs.generateImage(imagePath, size, false, req, res, next);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static generateIcon(req: Request, res: Response, next: NextFunction) {
|
||||||
|
if (!req.resultPipe)
|
||||||
|
return next();
|
||||||
|
|
||||||
|
//load parameters
|
||||||
|
let imagePath = req.resultPipe;
|
||||||
|
let size: number = 30;
|
||||||
|
ThumbnailGeneratorMWs.generateImage(imagePath, size, true, req, res, next);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static generateImage(imagePath, size, makeSquare, req: Request, res: Response, next: NextFunction) {
|
||||||
|
|
||||||
//generate thumbnail path
|
//generate thumbnail path
|
||||||
let thPath = path.join(ProjectPath.ThumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size));
|
let thPath = path.join(ProjectPath.ThumbnailFolder, ThumbnailGeneratorMWs.generateThumbnailName(imagePath, size));
|
||||||
|
|
||||||
@ -130,14 +154,12 @@ export class ThumbnailGeneratorMWs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//run on other thread
|
//run on other thread
|
||||||
pool.send({imagePath: imagePath, size: size, thPath: thPath})
|
pool.send({imagePath: imagePath, size: size, thPath: thPath, makeSquare: makeSquare})
|
||||||
.on('done', (out) => {
|
.on('done', (out) => {
|
||||||
return next(out);
|
return next(out);
|
||||||
}).on('error', (job, error) => {
|
}).on('error', (job, error) => {
|
||||||
return next(new Error(ErrorCodes.GENERAL_ERROR, error));
|
return next(new Error(ErrorCodes.GENERAL_ERROR, error));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static generateThumbnailName(imagePath: string, size: number): string {
|
private static generateThumbnailName(imagePath: string, size: number): string {
|
||||||
|
@ -6,6 +6,7 @@ import {ThumbnailGeneratorMWs} from "../middlewares/ThumbnailGeneratorMWs";
|
|||||||
export class GalleryRouter {
|
export class GalleryRouter {
|
||||||
constructor(private app: any) {
|
constructor(private app: any) {
|
||||||
|
|
||||||
|
this.addGetImageIcon();
|
||||||
this.addGetImageThumbnail();
|
this.addGetImageThumbnail();
|
||||||
this.addGetImage();
|
this.addGetImage();
|
||||||
this.addDirectoryList();
|
this.addDirectoryList();
|
||||||
@ -43,6 +44,15 @@ export class GalleryRouter {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private addGetImageIcon() {
|
||||||
|
this.app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/icon",
|
||||||
|
AuthenticationMWs.authenticate,
|
||||||
|
GalleryMWs.loadImage,
|
||||||
|
ThumbnailGeneratorMWs.generateIcon,
|
||||||
|
RenderingMWs.renderFile
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
private addSearch() {
|
private addSearch() {
|
||||||
this.app.get("/api/search/:text",
|
this.app.get("/api/search/:text",
|
||||||
AuthenticationMWs.authenticate,
|
AuthenticationMWs.authenticate,
|
||||||
|
@ -21,6 +21,8 @@ export class Server {
|
|||||||
private server: any;
|
private server: any;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
console.log("using config");
|
||||||
|
console.log(Config);
|
||||||
|
|
||||||
this.debug = _debug("PiGallery2:server");
|
this.debug = _debug("PiGallery2:server");
|
||||||
this.app = _express();
|
this.app = _express();
|
||||||
|
@ -34,6 +34,7 @@ interface ClientConfig {
|
|||||||
enableOnScrollRendering:boolean;
|
enableOnScrollRendering:boolean;
|
||||||
enableOnScrollThumbnailPrioritising:boolean;
|
enableOnScrollThumbnailPrioritising:boolean;
|
||||||
authenticationRequired:boolean;
|
authenticationRequired:boolean;
|
||||||
|
googleApiKey: string;
|
||||||
}
|
}
|
||||||
export class ConfigClass {
|
export class ConfigClass {
|
||||||
|
|
||||||
@ -50,7 +51,8 @@ export class ConfigClass {
|
|||||||
enableCache: false,
|
enableCache: false,
|
||||||
enableOnScrollRendering: true,
|
enableOnScrollRendering: true,
|
||||||
enableOnScrollThumbnailPrioritising: true,
|
enableOnScrollThumbnailPrioritising: true,
|
||||||
authenticationRequired: true
|
authenticationRequired: true,
|
||||||
|
googleApiKey: ""
|
||||||
};
|
};
|
||||||
|
|
||||||
public setDatabaseType(type:DatabaseType) {
|
public setDatabaseType(type:DatabaseType) {
|
||||||
|
@ -2,6 +2,7 @@ import {NgModule} from "@angular/core";
|
|||||||
import {BrowserModule} from "@angular/platform-browser";
|
import {BrowserModule} from "@angular/platform-browser";
|
||||||
import {FormsModule} from "@angular/forms";
|
import {FormsModule} from "@angular/forms";
|
||||||
import {HttpModule} from "@angular/http";
|
import {HttpModule} from "@angular/http";
|
||||||
|
import {AgmCoreModule} from "angular2-google-maps/core";
|
||||||
import {AppComponent} from "./app.component";
|
import {AppComponent} from "./app.component";
|
||||||
import {appRoutes} from "./app.routing";
|
import {appRoutes} from "./app.routing";
|
||||||
import {UserService} from "./model/network/user.service";
|
import {UserService} from "./model/network/user.service";
|
||||||
@ -25,13 +26,18 @@ import {LoginComponent} from "./login/login.component";
|
|||||||
import {AdminComponent} from "./admin/admin.component";
|
import {AdminComponent} from "./admin/admin.component";
|
||||||
import {GalleryComponent} from "./gallery/gallery.component";
|
import {GalleryComponent} from "./gallery/gallery.component";
|
||||||
import {StringifyRole} from "./pipes/StringifyRolePipe";
|
import {StringifyRole} from "./pipes/StringifyRolePipe";
|
||||||
|
import {Config} from "./config/Config";
|
||||||
|
import {GalleryMapComponent} from "./gallery/map/map.gallery.component";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpModule,
|
HttpModule,
|
||||||
appRoutes
|
appRoutes,
|
||||||
|
AgmCoreModule.forRoot({
|
||||||
|
apiKey: Config.Client.googleApiKey
|
||||||
|
})
|
||||||
],
|
],
|
||||||
declarations: [AppComponent,
|
declarations: [AppComponent,
|
||||||
LoginComponent,
|
LoginComponent,
|
||||||
@ -44,6 +50,7 @@ import {StringifyRole} from "./pipes/StringifyRolePipe";
|
|||||||
GalleryGridComponent,
|
GalleryGridComponent,
|
||||||
GalleryDirectoryComponent,
|
GalleryDirectoryComponent,
|
||||||
GalleryLightboxComponent,
|
GalleryLightboxComponent,
|
||||||
|
GalleryMapComponent,
|
||||||
FrameComponent,
|
FrameComponent,
|
||||||
GallerySearchComponent,
|
GallerySearchComponent,
|
||||||
GalleryNavigatorComponent,
|
GalleryNavigatorComponent,
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
.sebm-google-map-container {
|
||||||
|
height: 300px;
|
||||||
|
}
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.directory">
|
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.directory">
|
||||||
<gallery-navbar [directory]="_galleryService.content.directory"></gallery-navbar>
|
<gallery-navbar [directory]="_galleryService.content.directory"></gallery-navbar>
|
||||||
|
<gallery-map [photos]="_galleryService.content.directory.photos"></gallery-map>
|
||||||
<gallery-directory *ngFor="let directory of _galleryService.content.directory.directories"
|
<gallery-directory *ngFor="let directory of _galleryService.content.directory.directories"
|
||||||
[directory]="directory"></gallery-directory>
|
[directory]="directory"></gallery-directory>
|
||||||
<gallery-grid [photos]="_galleryService.content.directory.photos" [lightbox]="lightbox"></gallery-grid>
|
<gallery-grid [photos]="_galleryService.content.directory.photos" [lightbox]="lightbox"></gallery-grid>
|
||||||
@ -25,6 +26,9 @@
|
|||||||
<strong>{{_galleryService.content.searchResult.searchText}}</strong>
|
<strong>{{_galleryService.content.searchResult.searchText}}</strong>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
<gallery-map [photos]="_galleryService.content.searchResult.photos"></gallery-map>
|
||||||
|
|
||||||
<div *ngFor="let directory of _galleryService.content.searchResult.directories">
|
<div *ngFor="let directory of _galleryService.content.searchResult.directories">
|
||||||
<gallery-directory *ngIf="directory" [directory]="directory"></gallery-directory>
|
<gallery-directory *ngIf="directory" [directory]="directory"></gallery-directory>
|
||||||
</div>
|
</div>
|
||||||
|
4
frontend/app/gallery/map/map.gallery.component.css
Normal file
4
frontend/app/gallery/map/map.gallery.component.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.sebm-google-map-container {
|
||||||
|
height: 150px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
9
frontend/app/gallery/map/map.gallery.component.html
Normal file
9
frontend/app/gallery/map/map.gallery.component.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<sebm-google-map [zoom]="0">
|
||||||
|
<sebm-google-map-marker
|
||||||
|
|
||||||
|
*ngFor="let photo of mapPhotos"
|
||||||
|
[latitude]="photo.latitude"
|
||||||
|
[longitude]="photo.longitude"
|
||||||
|
[iconUrl]="photo.iconUrl">
|
||||||
|
</sebm-google-map-marker>
|
||||||
|
</sebm-google-map>
|
29
frontend/app/gallery/map/map.gallery.component.ts
Normal file
29
frontend/app/gallery/map/map.gallery.component.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import {Component, OnChanges, Input} from "@angular/core";
|
||||||
|
import {PhotoDTO} from "../../../../common/entities/PhotoDTO";
|
||||||
|
import {Utils} from "../../../../common/Utils";
|
||||||
|
@Component({
|
||||||
|
selector: 'gallery-map',
|
||||||
|
templateUrl: 'app/gallery/map/map.gallery.component.html',
|
||||||
|
styleUrls: ['app/gallery/map/map.gallery.component.css']
|
||||||
|
})
|
||||||
|
export class GalleryMapComponent implements OnChanges {
|
||||||
|
|
||||||
|
@Input() photos: Array<PhotoDTO>;
|
||||||
|
|
||||||
|
mapPhotos: Array<{latitude, longitude, iconUrl}> = [];
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: fix zooming
|
||||||
|
ngOnChanges() {
|
||||||
|
this.mapPhotos = this.photos.filter(p => p.metadata.positionData.GPSData).map(p => {
|
||||||
|
return {
|
||||||
|
latitude: p.metadata.positionData.GPSData.latitude,
|
||||||
|
longitude: p.metadata.positionData.GPSData.longitude,
|
||||||
|
iconUrl: Utils.concatUrls("/api/gallery/content/", p.directory.path, p.directory.name, p.name, "icon")
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
// other libraries
|
// other libraries
|
||||||
'rxjs': 'npm:rxjs',
|
'rxjs': 'npm:rxjs',
|
||||||
|
'angular2-google-maps': 'npm:angular2-google-maps',
|
||||||
'ng2-cookies': 'npm:ng2-cookies/ng2-cookies'
|
'ng2-cookies': 'npm:ng2-cookies/ng2-cookies'
|
||||||
},
|
},
|
||||||
// packages tells the System loader how to load when no filename and/or no extension
|
// packages tells the System loader how to load when no filename and/or no extension
|
||||||
@ -35,6 +36,10 @@
|
|||||||
},
|
},
|
||||||
rxjs: {
|
rxjs: {
|
||||||
defaultExtension: 'js'
|
defaultExtension: 'js'
|
||||||
|
},
|
||||||
|
"angular2-google-maps/core": {
|
||||||
|
"defaultExtension": "js",
|
||||||
|
"main": "index.js"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
"@angular/platform-browser-dynamic": "~2.4.1",
|
"@angular/platform-browser-dynamic": "~2.4.1",
|
||||||
"@angular/platform-server": "~2.4.1",
|
"@angular/platform-server": "~2.4.1",
|
||||||
"@angular/router": "~3.4.1",
|
"@angular/router": "~3.4.1",
|
||||||
|
"angular2-google-maps": "^0.17.0",
|
||||||
"body-parser": "^1.15.2",
|
"body-parser": "^1.15.2",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
"debug": "^2.6.0",
|
"debug": "^2.6.0",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user