Path performance improvements
- Avoid intermediate objects when creating leaflet objects to reduce allocations - Make individual path objects non-reactive - Avoid projecting path points twice during updates
This commit is contained in:
parent
9517de0760
commit
2a216dd4e8
@ -14,7 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {LatLngExpression, Polygon, PolylineOptions, Util} from "leaflet";
|
import {LatLngExpression, Polygon, PolylineOptions} from "leaflet";
|
||||||
|
import {LiveAtlasPath} from "@/index";
|
||||||
|
|
||||||
export interface LiveAtlasPolygonOptions extends PolylineOptions {
|
export interface LiveAtlasPolygonOptions extends PolylineOptions {
|
||||||
minZoom?: number;
|
minZoom?: number;
|
||||||
@ -22,8 +23,9 @@ export interface LiveAtlasPolygonOptions extends PolylineOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class LiveAtlasPolygon extends Polygon {
|
export default class LiveAtlasPolygon extends Polygon {
|
||||||
constructor(latlngs: LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][], options?: LiveAtlasPolygonOptions) {
|
declare options: LiveAtlasPolygonOptions;
|
||||||
super(latlngs, options);
|
|
||||||
Util.setOptions(this, options);
|
constructor(latlngs: LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][], options: LiveAtlasPath) {
|
||||||
|
super(latlngs, options.style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {LatLngExpression, Polyline, PolylineOptions, Util} from "leaflet";
|
import {LatLngExpression, Polyline, PolylineOptions} from "leaflet";
|
||||||
|
import {LiveAtlasPath} from "@/index";
|
||||||
|
|
||||||
export interface LiveAtlasPolylineOptions extends PolylineOptions {
|
export interface LiveAtlasPolylineOptions extends PolylineOptions {
|
||||||
minZoom?: number;
|
minZoom?: number;
|
||||||
@ -22,8 +23,11 @@ export interface LiveAtlasPolylineOptions extends PolylineOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default class LiveAtlasPolyline extends Polyline {
|
export default class LiveAtlasPolyline extends Polyline {
|
||||||
constructor(latlngs: LatLngExpression[] | LatLngExpression[][], options?: LiveAtlasPolylineOptions) {
|
declare options: LiveAtlasPolylineOptions;
|
||||||
super(latlngs, options);
|
|
||||||
Util.setOptions(this, options);
|
constructor(latlngs: LatLngExpression[] | LatLngExpression[][], option: LiveAtlasPath) {
|
||||||
|
super(latlngs, option.style);
|
||||||
|
this.options.minZoom = option.minZoom;
|
||||||
|
this.options.maxZoom = option.maxZoom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,30 +27,30 @@ export interface LiveAtlasProjectionOptions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class LiveAtlasProjection {
|
export class LiveAtlasProjection {
|
||||||
private readonly options: LiveAtlasProjectionOptions
|
private readonly mapToWorld: [number, number, number, number, number, number, number, number, number];
|
||||||
|
private readonly worldToMap: [number, number, number, number, number, number, number, number, number];
|
||||||
|
private readonly nativeZoomLevels: number;
|
||||||
|
|
||||||
constructor(options: LiveAtlasProjectionOptions) {
|
constructor(options: LiveAtlasProjectionOptions) {
|
||||||
this.options = {
|
this.mapToWorld = options.mapToWorld || [0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
mapToWorld: options.mapToWorld || [0, 0, 0, 0, 0, 0, 0, 0],
|
this.worldToMap = options.worldToMap || [0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
worldToMap: options.worldToMap || [0, 0, 0, 0, 0, 0, 0, 0],
|
this.nativeZoomLevels = options.nativeZoomLevels || 1;
|
||||||
nativeZoomLevels: options.nativeZoomLevels || 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
locationToLatLng(location: Coordinate): LatLng {
|
locationToLatLng(location: Coordinate): LatLng {
|
||||||
const wtp = this.options.worldToMap,
|
const wtp = this.worldToMap,
|
||||||
lat = wtp[3] * location.x + wtp[4] * location.y + wtp[5] * location.z,
|
lat = wtp[3] * location.x + wtp[4] * location.y + wtp[5] * location.z,
|
||||||
lng = wtp[0] * location.x + wtp[1] * location.y + wtp[2] * location.z;
|
lng = wtp[0] * location.x + wtp[1] * location.y + wtp[2] * location.z;
|
||||||
|
|
||||||
return new LatLng(
|
return new LatLng(
|
||||||
-((128 - lat) / (1 << this.options.nativeZoomLevels)),
|
-((128 - lat) / (1 << this.nativeZoomLevels)),
|
||||||
lng / (1 << this.options.nativeZoomLevels));
|
lng / (1 << this.nativeZoomLevels));
|
||||||
}
|
}
|
||||||
|
|
||||||
latLngToLocation(latLng: LatLng, y: number): Coordinate {
|
latLngToLocation(latLng: LatLng, y: number): Coordinate {
|
||||||
const ptw = this.options.mapToWorld,
|
const ptw = this.mapToWorld,
|
||||||
lat = latLng.lng * (1 << this.options.nativeZoomLevels),
|
lat = latLng.lng * (1 << this.nativeZoomLevels),
|
||||||
lon = 128 + latLng.lat * (1 << this.options.nativeZoomLevels),
|
lon = 128 + latLng.lat * (1 << this.nativeZoomLevels),
|
||||||
x = ptw[0] * lat + ptw[1] * lon + ptw[2] * y,
|
x = ptw[0] * lat + ptw[1] * lon + ptw[2] * y,
|
||||||
z = ptw[6] * lat + ptw[7] * lon + ptw[8] * y;
|
z = ptw[6] * lat + ptw[7] * lon + ptw[8] * y;
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ export default class DynmapMapProvider extends MapProvider {
|
|||||||
y: [number, number] = [area.ybottom || 0, area.ytop || 0],
|
y: [number, number] = [area.ybottom || 0, area.ytop || 0],
|
||||||
z = area.z || [0, 0];
|
z = area.z || [0, 0];
|
||||||
|
|
||||||
return {
|
return Object.seal({
|
||||||
style: {
|
style: {
|
||||||
color: area.color || '#ff0000',
|
color: area.color || '#ff0000',
|
||||||
opacity: area.opacity || 1,
|
opacity: area.opacity || 1,
|
||||||
@ -329,7 +329,7 @@ export default class DynmapMapProvider extends MapProvider {
|
|||||||
minZoom: typeof area.minzoom !== 'undefined' && area.minzoom > -1 ? area.minzoom : undefined,
|
minZoom: typeof area.minzoom !== 'undefined' && area.minzoom > -1 ? area.minzoom : undefined,
|
||||||
maxZoom: typeof area.maxzoom !== 'undefined' && area.maxzoom > -1 ? area.maxzoom : undefined,
|
maxZoom: typeof area.maxzoom !== 'undefined' && area.maxzoom > -1 ? area.maxzoom : undefined,
|
||||||
popupContent: area.desc || undefined,
|
popupContent: area.desc || undefined,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static buildLines(data: any): Map<string, LiveAtlasLine> {
|
private static buildLines(data: any): Map<string, LiveAtlasLine> {
|
||||||
@ -347,7 +347,7 @@ export default class DynmapMapProvider extends MapProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static buildLine(line: any): LiveAtlasLine {
|
private static buildLine(line: any): LiveAtlasLine {
|
||||||
return {
|
return Object.seal({
|
||||||
style: {
|
style: {
|
||||||
color: line.color || '#ff0000',
|
color: line.color || '#ff0000',
|
||||||
opacity: line.opacity || 1,
|
opacity: line.opacity || 1,
|
||||||
@ -359,7 +359,7 @@ export default class DynmapMapProvider extends MapProvider {
|
|||||||
minZoom: typeof line.minzoom !== 'undefined' && line.minzoom > -1 ? line.minzoom : undefined,
|
minZoom: typeof line.minzoom !== 'undefined' && line.minzoom > -1 ? line.minzoom : undefined,
|
||||||
maxZoom: typeof line.maxzoom !== 'undefined' && line.maxzoom > -1 ? line.maxzoom : undefined,
|
maxZoom: typeof line.maxzoom !== 'undefined' && line.maxzoom > -1 ? line.maxzoom : undefined,
|
||||||
popupContent: line.desc || undefined,
|
popupContent: line.desc || undefined,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static buildCircles(data: any): Map<string, LiveAtlasCircle> {
|
private static buildCircles(data: any): Map<string, LiveAtlasCircle> {
|
||||||
@ -377,7 +377,7 @@ export default class DynmapMapProvider extends MapProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static buildCircle(circle: any): LiveAtlasCircle {
|
private static buildCircle(circle: any): LiveAtlasCircle {
|
||||||
return {
|
return Object.seal({
|
||||||
location: {
|
location: {
|
||||||
x: circle.x || 0,
|
x: circle.x || 0,
|
||||||
y: circle.y || 0,
|
y: circle.y || 0,
|
||||||
@ -397,7 +397,7 @@ export default class DynmapMapProvider extends MapProvider {
|
|||||||
minZoom: typeof circle.minzoom !== 'undefined' && circle.minzoom > -1 ? circle.minzoom : undefined,
|
minZoom: typeof circle.minzoom !== 'undefined' && circle.minzoom > -1 ? circle.minzoom : undefined,
|
||||||
maxZoom: typeof circle.maxzoom !== 'undefined' && circle.maxzoom > -1 ? circle.maxzoom : undefined,
|
maxZoom: typeof circle.maxzoom !== 'undefined' && circle.maxzoom > -1 ? circle.maxzoom : undefined,
|
||||||
popupContent: circle.desc || undefined,
|
popupContent: circle.desc || undefined,
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildUpdates(data: Array<any>) {
|
private buildUpdates(data: Array<any>) {
|
||||||
|
@ -25,15 +25,7 @@ import {Coordinate, LiveAtlasArea} from "@/index";
|
|||||||
export const createArea = (options: LiveAtlasArea, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
export const createArea = (options: LiveAtlasArea, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||||
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
||||||
points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[] | LatLngExpression[][],
|
points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[] | LatLngExpression[][],
|
||||||
area = outline ? new LiveAtlasPolyline(points, {
|
area = outline ? new LiveAtlasPolyline(points, options) : new LiveAtlasPolygon(points, options);
|
||||||
...options.style,
|
|
||||||
minZoom: options.minZoom,
|
|
||||||
maxZoom: options.maxZoom,
|
|
||||||
}) : new LiveAtlasPolygon(points, {
|
|
||||||
...options.style,
|
|
||||||
minZoom: options.minZoom,
|
|
||||||
maxZoom: options.maxZoom,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (options.label) {
|
if (options.label) {
|
||||||
area.bindPopup(() => createPopup(options));
|
area.bindPopup(() => createPopup(options));
|
||||||
|
@ -25,15 +25,7 @@ import {LiveAtlasCircle} from "@/index";
|
|||||||
export const createCircle = (options: LiveAtlasCircle, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
export const createCircle = (options: LiveAtlasCircle, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||||
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
||||||
points = getCirclePoints(options, converter, outline),
|
points = getCirclePoints(options, converter, outline),
|
||||||
circle = outline ? new LiveAtlasPolyline(points, {
|
circle = outline ? new LiveAtlasPolyline(points, options) : new LiveAtlasPolygon(points, options);
|
||||||
...options.style,
|
|
||||||
minZoom: options.minZoom,
|
|
||||||
maxZoom: options.maxZoom,
|
|
||||||
}) : new LiveAtlasPolygon(points, {
|
|
||||||
...options.style,
|
|
||||||
minZoom: options.minZoom,
|
|
||||||
maxZoom: options.maxZoom,
|
|
||||||
});
|
|
||||||
|
|
||||||
if(options.label) {
|
if(options.label) {
|
||||||
circle.bindPopup(() => createPopup(options));
|
circle.bindPopup(() => createPopup(options));
|
||||||
@ -43,18 +35,17 @@ export const createCircle = (options: LiveAtlasCircle, converter: Function): Liv
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const updateCircle = (circle: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasCircle, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
export const updateCircle = (circle: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasCircle, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||||
const outline = (options.style && options.style.fillOpacity && (options.style.fillOpacity <= 0)) as boolean,
|
|
||||||
points = getCirclePoints(options, converter, outline);
|
|
||||||
|
|
||||||
if (!circle) {
|
if (!circle) {
|
||||||
return createCircle(options, converter);
|
return createCircle(options, converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const outline = (options.style && options.style.fillOpacity && (options.style.fillOpacity <= 0)) as boolean;
|
||||||
|
|
||||||
circle.closePopup();
|
circle.closePopup();
|
||||||
circle.unbindPopup();
|
circle.unbindPopup();
|
||||||
circle.bindPopup(() => createPopup(options));
|
circle.bindPopup(() => createPopup(options));
|
||||||
circle.setStyle(options.style);
|
circle.setStyle(options.style);
|
||||||
circle.setLatLngs(points);
|
circle.setLatLngs(getCirclePoints(options, converter, outline));
|
||||||
circle.redraw();
|
circle.redraw();
|
||||||
|
|
||||||
return circle;
|
return circle;
|
||||||
|
@ -22,12 +22,8 @@ import {Coordinate, LiveAtlasLine} from "@/index";
|
|||||||
import {LatLngExpression} from "leaflet";
|
import {LatLngExpression} from "leaflet";
|
||||||
|
|
||||||
export const createLine = (options: LiveAtlasLine, converter: Function): LiveAtlasPolyline => {
|
export const createLine = (options: LiveAtlasLine, converter: Function): LiveAtlasPolyline => {
|
||||||
const points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[],
|
const points = options.points.map(projectPointsMapCallback, converter),
|
||||||
line = new LiveAtlasPolyline(points, {
|
line = new LiveAtlasPolyline(points, options);
|
||||||
...options.style,
|
|
||||||
minZoom: options.minZoom,
|
|
||||||
maxZoom: options.maxZoom,
|
|
||||||
});
|
|
||||||
|
|
||||||
if(options.label) {
|
if(options.label) {
|
||||||
line.bindPopup(() => createPopup(options));
|
line.bindPopup(() => createPopup(options));
|
||||||
@ -37,8 +33,6 @@ export const createLine = (options: LiveAtlasLine, converter: Function): LiveAtl
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const updateLine = (line: LiveAtlasPolyline | undefined, options: LiveAtlasLine, converter: Function): LiveAtlasPolyline => {
|
export const updateLine = (line: LiveAtlasPolyline | undefined, options: LiveAtlasLine, converter: Function): LiveAtlasPolyline => {
|
||||||
const points = options.points.map(projectPointsMapCallback, converter);
|
|
||||||
|
|
||||||
if (!line) {
|
if (!line) {
|
||||||
return createLine(options, converter);
|
return createLine(options, converter);
|
||||||
}
|
}
|
||||||
@ -47,7 +41,7 @@ export const updateLine = (line: LiveAtlasPolyline | undefined, options: LiveAtl
|
|||||||
line.unbindPopup();
|
line.unbindPopup();
|
||||||
line.bindPopup(() => createPopup(options));
|
line.bindPopup(() => createPopup(options));
|
||||||
line.setStyle(options.style);
|
line.setStyle(options.style);
|
||||||
line.setLatLngs(points);
|
line.setLatLngs(options.points.map(projectPointsMapCallback, converter));
|
||||||
line.redraw();
|
line.redraw();
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
|
Loading…
Reference in New Issue
Block a user