Skip to content

Commit

Permalink
fix(styler): Parse QML styles loaded via URL
Browse files Browse the repository at this point in the history
Move base64 icon fix to separate function and file
  • Loading branch information
FilipLeitner authored and jmacura committed Jul 18, 2024
1 parent 6bc2182 commit 2e07f3c
Showing 4 changed files with 30 additions and 18 deletions.
15 changes: 9 additions & 6 deletions projects/hslayers/common/layman/layman.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import {HttpClient, HttpHeaders} from '@angular/common/http';
import {Injectable} from '@angular/core';

import {BehaviorSubject, Subject, lastValueFrom} from 'rxjs';
import {BehaviorSubject, Subject, lastValueFrom, map} from 'rxjs';

import {CurrentUserResponse} from './types/current-user-response.type';
import {HsEndpoint} from 'hslayers-ng/types';
import {HsLanguageService} from 'hslayers-ng/services/language';
import {HsLogService} from 'hslayers-ng/services/log';
import {HsToastService} from 'hslayers-ng/common/toast';
import {parseBase64Style} from './parse-base64-style';

@Injectable({
providedIn: 'root',
@@ -131,11 +132,13 @@ export class HsCommonLaymanService {
async getStyleFromUrl(styleUrl: string): Promise<string> {
try {
return await lastValueFrom(
this.$http.get(styleUrl, {
headers: new HttpHeaders().set('Content-Type', 'text'),
responseType: 'text',
withCredentials: true,
}),
this.$http
.get(styleUrl, {
headers: new HttpHeaders().set('Content-Type', 'text'),
responseType: 'text',
withCredentials: true,
})
.pipe(map((response) => parseBase64Style(response))),
);
} catch (ex) {
this.hsLog.error(ex);
15 changes: 15 additions & 0 deletions projects/hslayers/common/layman/parse-base64-style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Parse QML string style and make base64 symbols usable in browser by
*
* Look for prop elements with source attribute
* and prepend its content to v while switching : with ,
*/
export function parseBase64Style(styleString: string) {
const regex = /<prop([^>]*source="(data:[^"]*)"[^>]*v="base64:([^"]*)")/g;

return styleString.startsWith('<qgis')
? styleString.replace(regex, (match, p1, p2, p3) => {
return match.replace(`v="base64:${p3}"`, `v="${p2}base64,${p3}"`);
})
: styleString;
}
1 change: 1 addition & 0 deletions projects/hslayers/common/layman/public-api.ts
Original file line number Diff line number Diff line change
@@ -10,3 +10,4 @@ export * from './types/delete-layer-response.type';
export * from './types/layman-user.type';
export * from './layman-utils';
export * from './transliteration-map';
export * from './parse-base64-style';
17 changes: 5 additions & 12 deletions projects/hslayers/services/styler/styler.service.ts
Original file line number Diff line number Diff line change
@@ -22,7 +22,10 @@ import {Layer, Vector as VectorLayer} from 'ol/layer';
import {OlStyleParser as OpenLayersParser} from 'geostyler-openlayers-parser';
import {StyleFunction, StyleLike, createDefaultStyle} from 'ol/style/Style';

import {HsCommonLaymanService} from 'hslayers-ng/common/layman';
import {
HsCommonLaymanService,
parseBase64Style,
} from 'hslayers-ng/common/layman';
import {HsConfig} from 'hslayers-ng/config';
import {HsConfirmDialogComponent} from 'hslayers-ng/common/confirm';
import {HsDialogContainerService} from 'hslayers-ng/common/dialogs';
@@ -797,17 +800,7 @@ export class HsStylerService {
const qmlParser = new QGISStyleParser();
await qmlParser.readStyle(styleString);

/**
* Parse QML string:
* Look for prop elements with source attribute
* and prepend its content to v while switching : with ,
*/
const regex =
/<prop([^>]*source="(data:[^"]*)"[^>]*v="base64:([^"]*)")/g;

this.qml = styleString.replace(regex, (match, p1, p2, p3) => {
return match.replace(`v="base64:${p3}"`, `v="${p2}base64,${p3}"`);
});
this.qml = parseBase64Style(styleString);
}
this.resolveSldChange();
this.fill(this.layer, styleFmt);

0 comments on commit 2e07f3c

Please sign in to comment.