feat: initialize drainage network frontend
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import type { Map as MapLibreMap, PaddingOptions } from "maplibre-gl";
|
||||
import { WATER_NETWORK_GLOBAL_VIEW } from "./sources";
|
||||
|
||||
type LngLatBounds = [[number, number], [number, number]];
|
||||
type WebMercatorBbox = readonly [number, number, number, number];
|
||||
|
||||
export type NetworkViewParams = {
|
||||
bbox3857: WebMercatorBbox;
|
||||
};
|
||||
|
||||
const WEB_MERCATOR_RADIUS = 6378137;
|
||||
const NO_PADDING: PaddingOptions = { top: 0, right: 0, bottom: 0, left: 0 };
|
||||
|
||||
export function getWorkbenchPadding(leftPanelOpen: boolean, rightPanelOpen: boolean): PaddingOptions {
|
||||
return {
|
||||
top: 88,
|
||||
left: leftPanelOpen ? 530 : 88,
|
||||
right: rightPanelOpen ? 430 : 120,
|
||||
bottom: 96
|
||||
};
|
||||
}
|
||||
|
||||
export function getResponsiveWorkbenchPadding(
|
||||
map: MapLibreMap,
|
||||
leftPanelOpen: boolean,
|
||||
rightPanelOpen: boolean
|
||||
): PaddingOptions {
|
||||
return getResponsivePadding(map, getWorkbenchPadding(leftPanelOpen, rightPanelOpen));
|
||||
}
|
||||
|
||||
export function fitNetworkBounds(
|
||||
map: MapLibreMap,
|
||||
viewParams: NetworkViewParams = WATER_NETWORK_GLOBAL_VIEW,
|
||||
padding: PaddingOptions = NO_PADDING
|
||||
) {
|
||||
map.fitBounds(
|
||||
getLngLatBoundsFromBbox3857(viewParams.bbox3857),
|
||||
{ padding: getResponsivePadding(map, padding), duration: 600 }
|
||||
);
|
||||
}
|
||||
|
||||
function getResponsivePadding(map: MapLibreMap, padding: PaddingOptions): PaddingOptions {
|
||||
const canvas = map.getCanvas();
|
||||
const width = canvas.clientWidth || canvas.width;
|
||||
const height = canvas.clientHeight || canvas.height;
|
||||
const horizontalPadding = padding.left + padding.right;
|
||||
const verticalPadding = padding.top + padding.bottom;
|
||||
const maxHorizontalPadding = width * 0.58;
|
||||
const maxVerticalPadding = height * 0.58;
|
||||
const horizontalScale = horizontalPadding > 0 ? maxHorizontalPadding / horizontalPadding : 1;
|
||||
const verticalScale = verticalPadding > 0 ? maxVerticalPadding / verticalPadding : 1;
|
||||
const scale = Math.min(1, horizontalScale, verticalScale);
|
||||
|
||||
if (scale >= 1) {
|
||||
return padding;
|
||||
}
|
||||
|
||||
return {
|
||||
top: Math.round(padding.top * scale),
|
||||
right: Math.round(padding.right * scale),
|
||||
bottom: Math.round(padding.bottom * scale),
|
||||
left: Math.round(padding.left * scale)
|
||||
};
|
||||
}
|
||||
|
||||
function getLngLatBoundsFromBbox3857(bbox3857: WebMercatorBbox): LngLatBounds {
|
||||
const [minX, minY, maxX, maxY] = bbox3857;
|
||||
|
||||
return [
|
||||
webMercatorToLngLat(minX, minY),
|
||||
webMercatorToLngLat(maxX, maxY)
|
||||
];
|
||||
}
|
||||
|
||||
function webMercatorToLngLat(x: number, y: number): [number, number] {
|
||||
const lng = (x / WEB_MERCATOR_RADIUS) * (180 / Math.PI);
|
||||
const lat = (2 * Math.atan(Math.exp(y / WEB_MERCATOR_RADIUS)) - Math.PI / 2) * (180 / Math.PI);
|
||||
|
||||
return [lng, lat];
|
||||
}
|
||||
Reference in New Issue
Block a user