Skip to content

Commit

Permalink
Typescript migration (#123)
Browse files Browse the repository at this point in the history
Signed-off-by: Franck LECUYER <franck.lecuyer@rte-france.com>
Co-authored-by: Arnaud Marant <133104748+amarant@users.noreply.github.com>
Co-authored-by: Tristan Chuine <tristan.chuine_externe@rte-france.com>
  • Loading branch information
3 people authored Nov 21, 2024
1 parent d806c92 commit 4c6e26f
Show file tree
Hide file tree
Showing 13 changed files with 1,728 additions and 1,200 deletions.
2 changes: 1 addition & 1 deletion demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
import { useEffect, useRef } from 'react';
import { createTheme, StyledEngineProvider, ThemeProvider } from '@mui/material/styles';
import { GeoData, NetworkMap, NetworkMapRef } from '../../src';
import { Equipment } from '../../src/components/network-map-viewer/network/map-equipments';
import { addNadToDemo, addSldToDemo } from './diagram-viewers/add-diagrams';
import DemoMapEquipments from './map-viewer/demo-map-equipments';

import sposdata from './map-viewer/data/spos.json';
import lposdata from './map-viewer/data/lpos.json';
import smapdata from './map-viewer/data/smap.json';
import lmapdata from './map-viewer/data/lmap.json';
import { Equipment } from '../../src/components/network-map-viewer/utils/equipment-types';

export default function App() {
const INITIAL_ZOOM = 9;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,49 @@
import { computeDestinationPoint, getGreatCircleBearing, getRhumbLineBearing } from 'geolib';
import cheapRuler from 'cheap-ruler';
import { ArrowDirection } from './layers/arrow-layer';
import { Line, LonLat } from '../utils/equipment-types';
import { MapEquipments } from './map-equipments';

const substationPositionByIdIndexer = (map, substation) => {
export type Coordinate = {
lon: number;
lat: number;
};

export type SubstationPosition = {
id: string;
coordinate: Coordinate;
};

export type LinePosition = {
id: string;
coordinates: Coordinate[];
};

const substationPositionByIdIndexer = (map: Map<string, Coordinate>, substation: SubstationPosition) => {
map.set(substation.id, substation.coordinate);
return map;
};

const linePositionByIdIndexer = (map, line) => {
const linePositionByIdIndexer = (map: Map<string, Coordinate[]>, line: LinePosition) => {
map.set(line.id, line.coordinates);
return map;
};

export class GeoData {
substationPositionsById = new Map();

linePositionsById = new Map();
substationPositionsById = new Map<string, Coordinate>();
linePositionsById = new Map<string, Coordinate[]>();

constructor(substationPositionsById, linePositionsById) {
constructor(substationPositionsById: Map<string, Coordinate>, linePositionsById: Map<string, Coordinate[]>) {
this.substationPositionsById = substationPositionsById;
this.linePositionsById = linePositionsById;
}

setSubstationPositions(positions) {
setSubstationPositions(positions: SubstationPosition[]) {
// index positions by substation id
this.substationPositionsById = positions.reduce(substationPositionByIdIndexer, new Map());
}

updateSubstationPositions(substationIdsToUpdate, fetchedPositions) {
updateSubstationPositions(substationIdsToUpdate: string[], fetchedPositions: SubstationPosition[]) {
fetchedPositions.forEach((pos) => this.substationPositionsById.set(pos.id, pos.coordinate));
// If a substation position is requested but not present in the fetched results, we delete its position.
// It allows to cancel the position of a substation when the server can't situate it anymore after a network modification (for example a line deletion).
Expand All @@ -43,7 +59,7 @@ export class GeoData {
.forEach((id) => this.substationPositionsById.delete(id));
}

getSubstationPosition(substationId) {
getSubstationPosition(substationId: string): LonLat {
const position = this.substationPositionsById.get(substationId);
if (!position) {
console.warn(`Position not found for ${substationId}`);
Expand All @@ -52,12 +68,12 @@ export class GeoData {
return [position.lon, position.lat];
}

setLinePositions(positions) {
setLinePositions(positions: LinePosition[]) {
// index positions by line id
this.linePositionsById = positions.reduce(linePositionByIdIndexer, new Map());
}

updateLinePositions(lineIdsToUpdate, fetchedPositions) {
updateLinePositions(lineIdsToUpdate: string[], fetchedPositions: LinePosition[]) {
fetchedPositions.forEach((pos) => {
this.linePositionsById.set(pos.id, pos.coordinates);
});
Expand All @@ -72,7 +88,7 @@ export class GeoData {
/**
* Get line positions always ordered from side 1 to side 2.
*/
getLinePositions(network, line, detailed = true) {
getLinePositions(network: MapEquipments, line: Line, detailed = true): LonLat[] {
const voltageLevel1 = network.getVoltageLevel(line.voltageLevelId1);
if (!voltageLevel1) {
throw new Error(`Voltage level side 1 '${line.voltageLevelId1}' not found`);
Expand Down Expand Up @@ -101,7 +117,7 @@ export class GeoData {
const linePositions = this.linePositionsById.get(line.id);
// Is there any position for this line ?
if (linePositions) {
const positions = new Array(linePositions.length);
const positions = new Array<LonLat>(linePositions.length);

for (const [index, position] of linePositions.entries()) {
positions[index] = [position.lon, position.lat];
Expand All @@ -114,9 +130,9 @@ export class GeoData {
return [substationPosition1, substationPosition2];
}

getLineDistances(positions) {
getLineDistances(positions: LonLat[]) {
if (positions !== null && positions.length > 1) {
let cumulativeDistanceArray = [0];
const cumulativeDistanceArray = [0];
let cumulativeDistance = 0;
let segmentDistance;
let ruler;
Expand All @@ -136,13 +152,13 @@ export class GeoData {
* along with the remaining distance to travel on this segment to be at the exact wanted distance
* (implemented using a binary search)
*/
findSegment(positions, cumulativeDistances, wantedDistance) {
findSegment(positions: LonLat[], cumulativeDistances: number[], wantedDistance: number) {
let lowerBound = 0;
let upperBound = cumulativeDistances.length - 1;
let middlePoint;
while (lowerBound + 1 !== upperBound) {
middlePoint = Math.floor((lowerBound + upperBound) / 2);
let middlePointDistance = cumulativeDistances[middlePoint];
const middlePointDistance = cumulativeDistances[middlePoint];
if (middlePointDistance <= wantedDistance) {
lowerBound = middlePoint;
} else {
Expand All @@ -151,21 +167,21 @@ export class GeoData {
}
return {
idx: lowerBound,
segment: positions.slice(lowerBound, lowerBound + 2),
segment: positions.slice(lowerBound, lowerBound + 2) as [LonLat, LonLat],
remainingDistance: wantedDistance - cumulativeDistances[lowerBound],
};
}

labelDisplayPosition(
positions,
cumulativeDistances,
arrowPosition,
arrowDirection,
lineParallelIndex,
lineAngle,
proximityAngle,
distanceBetweenLines,
proximityFactor
positions: LonLat[],
cumulativeDistances: number[],
arrowPosition: number,
arrowDirection: ArrowDirection,
lineParallelIndex: number,
lineAngle: number,
proximityAngle: number,
distanceBetweenLines: number,
proximityFactor: number
) {
if (arrowPosition > 1 || arrowPosition < 0) {
throw new Error('Proportional position value incorrect: ' + arrowPosition);
Expand All @@ -177,7 +193,7 @@ export class GeoData {
) {
return null;
}
let lineDistance = cumulativeDistances[cumulativeDistances.length - 1];
const lineDistance = cumulativeDistances[cumulativeDistances.length - 1];
let wantedDistance = lineDistance * arrowPosition;

if (cumulativeDistances.length === 2) {
Expand All @@ -187,7 +203,7 @@ export class GeoData {
wantedDistance = wantedDistance - 2 * distanceBetweenLines * arrowPosition * proximityFactor;
}

let goodSegment = this.findSegment(positions, cumulativeDistances, wantedDistance);
const goodSegment = this.findSegment(positions, cumulativeDistances, wantedDistance);

// We don't have the exact same distance calculation as in the arrow shader, so take some margin:
// we move the label a little bit on the flat side of the arrow so that at least it stays
Expand All @@ -206,9 +222,9 @@ export class GeoData {
default:
throw new Error('impossible');
}
let remainingDistance = goodSegment.remainingDistance * multiplier;
const remainingDistance = goodSegment.remainingDistance * multiplier;

let angle = this.getMapAngle(goodSegment.segment[0], goodSegment.segment[1]);
const angle = this.getMapAngle(goodSegment.segment[0], goodSegment.segment[1]);
const neededOffset = this.getLabelOffset(angle, 20, arrowDirection);

const position = {
Expand Down Expand Up @@ -252,8 +268,8 @@ export class GeoData {
return position;
}

getLabelOffset(angle, offsetDistance, arrowDirection) {
let radiantAngle = (-angle + 90) / (180 / Math.PI);
getLabelOffset(angle: number, offsetDistance: number, arrowDirection: ArrowDirection): [number, number] {
const radiantAngle = (-angle + 90) / (180 / Math.PI);
let direction = 0;
switch (arrowDirection) {
case ArrowDirection.FROM_SIDE_2_TO_SIDE_1:
Expand All @@ -276,11 +292,11 @@ export class GeoData {
}

//returns the angle between point1 and point2 in degrees [0-360)
getMapAngle(point1, point2) {
getMapAngle(point1: LonLat, point2: LonLat) {
// We don't have the exact same angle calculation as in the arrow shader, and this
// seems to give more approaching results
let angle = getRhumbLineBearing(point1, point2);
let angle2 = getGreatCircleBearing(point1, point2);
const angle2 = getGreatCircleBearing(point1, point2);
const coeff = 0.1;
angle = coeff * angle + (1 - coeff) * angle2;
return angle;
Expand Down
Loading

0 comments on commit 4c6e26f

Please sign in to comment.