wip: partial TypeScript fixes for open-mapping module
Progress on task-040 (Open-Mapping Production Ready): - Added GeohashPrecision re-export and GeohashCommitment type alias - Added convenience aliases for geohash functions (encodeGeohash, etc.) - Added vector operation aliases in conics/geometry.ts - Added combineCones, sliceConeWithPlane, angleFromAxis functions - Fixed type annotations in RoutingService and OptimizationService - Added sourceConstraints property to PossibilityCone - Suppressed unused parameter warnings in stub components - Re-enabled open-mapping in tsconfig (with exclusions for broken files) Remaining work (~51 errors): - Fix discovery module (MyceliumNetwork missing methods) - Fix CollaborativeMap and MapCanvas coordinate types - Fix remaining unused parameters in optimization.ts, useCollaboration.ts - Fix presence manager function signatures 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
af6666bf72
commit
f440c4d5e1
|
|
@ -24,12 +24,18 @@ interface LayerPanelProps {
|
||||||
export function LayerPanel({
|
export function LayerPanel({
|
||||||
layers,
|
layers,
|
||||||
onLayerToggle,
|
onLayerToggle,
|
||||||
onLayerOpacity,
|
onLayerOpacity: _onLayerOpacity,
|
||||||
onLayerReorder,
|
onLayerReorder: _onLayerReorder,
|
||||||
onLayerAdd,
|
onLayerAdd: _onLayerAdd,
|
||||||
onLayerRemove,
|
onLayerRemove: _onLayerRemove,
|
||||||
onLayerEdit,
|
onLayerEdit: _onLayerEdit,
|
||||||
}: LayerPanelProps) {
|
}: LayerPanelProps) {
|
||||||
|
// Suppress unused variable warnings for future implementation
|
||||||
|
void _onLayerOpacity;
|
||||||
|
void _onLayerReorder;
|
||||||
|
void _onLayerAdd;
|
||||||
|
void _onLayerRemove;
|
||||||
|
void _onLayerEdit;
|
||||||
// TODO: Implement layer panel UI
|
// TODO: Implement layer panel UI
|
||||||
// This will be implemented in Phase 2
|
// This will be implemented in Phase 2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,16 +34,25 @@ const DEFAULT_PROFILE_COLORS: Record<RoutingProfile, string> = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function RouteLayer({
|
export function RouteLayer({
|
||||||
routes,
|
routes: _routes,
|
||||||
selectedRouteId,
|
selectedRouteId: _selectedRouteId,
|
||||||
showAlternatives = true,
|
showAlternatives: _showAlternatives = true,
|
||||||
showElevation = false,
|
showElevation: _showElevation = false,
|
||||||
onRouteSelect,
|
onRouteSelect: _onRouteSelect,
|
||||||
onRouteEdit,
|
onRouteEdit: _onRouteEdit,
|
||||||
profileColors = {},
|
profileColors = {},
|
||||||
}: RouteLayerProps) {
|
}: RouteLayerProps) {
|
||||||
const colors = { ...DEFAULT_PROFILE_COLORS, ...profileColors };
|
const colors = { ...DEFAULT_PROFILE_COLORS, ...profileColors };
|
||||||
|
|
||||||
|
// Suppress unused variable warnings for future implementation
|
||||||
|
void _routes;
|
||||||
|
void _selectedRouteId;
|
||||||
|
void _showAlternatives;
|
||||||
|
void _showElevation;
|
||||||
|
void _onRouteSelect;
|
||||||
|
void _onRouteEdit;
|
||||||
|
void colors;
|
||||||
|
|
||||||
// TODO: Implement route rendering with MapLibre GL JS
|
// TODO: Implement route rendering with MapLibre GL JS
|
||||||
// This will be implemented in Phase 2
|
// This will be implemented in Phase 2
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,20 +23,10 @@ interface WaypointMarkerProps {
|
||||||
onDelete?: (waypointId: string) => void;
|
onDelete?: (waypointId: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function WaypointMarker({
|
export function WaypointMarker(_props: WaypointMarkerProps) {
|
||||||
waypoint,
|
|
||||||
index,
|
|
||||||
isSelected = false,
|
|
||||||
isDraggable = true,
|
|
||||||
showLabel = true,
|
|
||||||
showTime = false,
|
|
||||||
showBudget = false,
|
|
||||||
onSelect,
|
|
||||||
onDragEnd,
|
|
||||||
onDelete,
|
|
||||||
}: WaypointMarkerProps) {
|
|
||||||
// TODO: Implement marker rendering with MapLibre GL JS
|
// TODO: Implement marker rendering with MapLibre GL JS
|
||||||
// This will be implemented in Phase 1
|
// Props will be used in Phase 1 implementation
|
||||||
|
void _props;
|
||||||
|
|
||||||
return null; // Markers are rendered directly on the map
|
return null; // Markers are rendered directly on the map
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -636,3 +636,81 @@ function findOrthogonalVector(v: SpaceVector): SpaceVector {
|
||||||
|
|
||||||
return normalize(result);
|
return normalize(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Convenience Aliases (for backwards compatibility with index.ts exports)
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
export const vectorAdd = addVectors;
|
||||||
|
export const vectorSubtract = subtractVectors;
|
||||||
|
export const vectorScale = scaleVector;
|
||||||
|
export const vectorDot = dotProduct;
|
||||||
|
export const vectorNorm = magnitude;
|
||||||
|
export const vectorNormalize = normalize;
|
||||||
|
export const vectorCross3D = crossProduct;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate angle from cone axis to a point
|
||||||
|
*/
|
||||||
|
export function angleFromAxis(point: SpacePoint, cone: PossibilityCone): number {
|
||||||
|
const toPoint = subtractVectors(pointToVector(point), pointToVector(cone.apex));
|
||||||
|
const toPointNorm = normalize(toPoint);
|
||||||
|
const dot = dotProduct(toPointNorm, cone.axis);
|
||||||
|
return Math.acos(Math.max(-1, Math.min(1, dot)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combine two cones (union/intersection)
|
||||||
|
*/
|
||||||
|
export function combineCones(
|
||||||
|
cone1: PossibilityCone,
|
||||||
|
cone2: PossibilityCone,
|
||||||
|
operation: 'union' | 'intersection' = 'intersection'
|
||||||
|
): PossibilityCone {
|
||||||
|
// For intersection, take the narrower aperture
|
||||||
|
// For union, take the wider aperture
|
||||||
|
const aperture = operation === 'intersection'
|
||||||
|
? Math.min(cone1.aperture, cone2.aperture)
|
||||||
|
: Math.max(cone1.aperture, cone2.aperture);
|
||||||
|
|
||||||
|
// Average the apex positions
|
||||||
|
const apex: SpacePoint = {
|
||||||
|
coordinates: cone1.apex.coordinates.map((c, i) =>
|
||||||
|
(c + (cone2.apex.coordinates[i] ?? 0)) / 2
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Average the axes (normalized)
|
||||||
|
const avgAxis = normalize(addVectors(cone1.axis, cone2.axis));
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: `${cone1.id}-${cone2.id}-${operation}`,
|
||||||
|
apex,
|
||||||
|
axis: avgAxis,
|
||||||
|
aperture,
|
||||||
|
direction: cone1.direction,
|
||||||
|
extent: cone1.extent && cone2.extent
|
||||||
|
? Math.min(cone1.extent, cone2.extent)
|
||||||
|
: cone1.extent ?? cone2.extent,
|
||||||
|
constraints: [...cone1.constraints, ...cone2.constraints],
|
||||||
|
sourceConstraints: [
|
||||||
|
...(cone1.sourceConstraints ?? []),
|
||||||
|
...(cone2.sourceConstraints ?? []),
|
||||||
|
],
|
||||||
|
metadata: { ...cone1.metadata, ...cone2.metadata },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Slice a cone with a hyperplane to get a conic section
|
||||||
|
*/
|
||||||
|
export function sliceConeWithPlane(
|
||||||
|
cone: PossibilityCone,
|
||||||
|
planeNormal: SpaceVector,
|
||||||
|
planePoint: SpacePoint
|
||||||
|
): ConicSection {
|
||||||
|
// Calculate plane offset as distance from origin along normal
|
||||||
|
const planeOffset = dotProduct(pointToVector(planePoint), planeNormal);
|
||||||
|
|
||||||
|
return createConicSection(cone, planeNormal, planeOffset);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -745,3 +745,13 @@ export function createPathOptimizer(
|
||||||
): PathOptimizer {
|
): PathOptimizer {
|
||||||
return new PathOptimizer(bounds, config);
|
return new PathOptimizer(bounds, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Re-export config types from types.ts for convenience
|
||||||
|
export { DEFAULT_OPTIMIZATION_CONFIG } from './types';
|
||||||
|
export type { OptimizationConfig } from './types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for backwards compatibility with index.ts
|
||||||
|
*/
|
||||||
|
export const DEFAULT_OPTIMIZER_CONFIG = DEFAULT_OPTIMIZATION_CONFIG;
|
||||||
|
export type OptimizerConfig = OptimizationConfig;
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,9 @@ export interface PossibilityCone {
|
||||||
/** Constraints that shaped this cone */
|
/** Constraints that shaped this cone */
|
||||||
constraints: string[];
|
constraints: string[];
|
||||||
|
|
||||||
|
/** Source constraints (for combined cones) */
|
||||||
|
sourceConstraints?: string[];
|
||||||
|
|
||||||
/** Metadata */
|
/** Metadata */
|
||||||
metadata: Record<string, unknown>;
|
metadata: Record<string, unknown>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -427,3 +427,16 @@ export function precisionForRadius(radiusMeters: number): number {
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Convenience Aliases (for backwards compatibility)
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
/** Alias for encode() */
|
||||||
|
export const encodeGeohash = encode;
|
||||||
|
|
||||||
|
/** Alias for decode() */
|
||||||
|
export const decodeGeohash = decode;
|
||||||
|
|
||||||
|
/** Alias for decodeBounds() */
|
||||||
|
export const getGeohashBounds = decodeBounds;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
* Types for privacy-preserving location sharing protocol
|
* Types for privacy-preserving location sharing protocol
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Re-export GeohashPrecision so consumers can import from types
|
||||||
|
export type { GeohashPrecision } from './geohash';
|
||||||
import type { GeohashPrecision } from './geohash';
|
import type { GeohashPrecision } from './geohash';
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
@ -49,6 +51,9 @@ export interface LocationCommitment {
|
||||||
|
|
||||||
/** Optional: the geohash prefix that is publicly revealed */
|
/** Optional: the geohash prefix that is publicly revealed */
|
||||||
revealedPrefix?: string;
|
revealedPrefix?: string;
|
||||||
|
|
||||||
|
/** The geohash string (at the given precision) */
|
||||||
|
geohash?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -72,6 +77,11 @@ export interface SignedCommitment extends LocationCommitment {
|
||||||
signerPublicKey: string;
|
signerPublicKey: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for LocationCommitment (used by discovery module)
|
||||||
|
*/
|
||||||
|
export type GeohashCommitment = LocationCommitment;
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Trust Circle Types
|
// Trust Circle Types
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,16 @@
|
||||||
|
|
||||||
import type { Waypoint, Coordinate, OptimizationServiceConfig } from '../types';
|
import type { Waypoint, Coordinate, OptimizationServiceConfig } from '../types';
|
||||||
|
|
||||||
|
// VROOM API response type
|
||||||
|
interface VROOMResponse {
|
||||||
|
code: number;
|
||||||
|
error?: string;
|
||||||
|
summary: { distance: number; duration: number };
|
||||||
|
routes: Array<{
|
||||||
|
steps: Array<{ type: string; job?: number }>;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
export interface OptimizationResult {
|
export interface OptimizationResult {
|
||||||
orderedWaypoints: Waypoint[];
|
orderedWaypoints: Waypoint[];
|
||||||
totalDistance: number;
|
totalDistance: number;
|
||||||
|
|
@ -50,10 +60,10 @@ export class OptimizationService {
|
||||||
const vehicles = [{ id: 0, start: [waypoints[0].coordinate.lng, waypoints[0].coordinate.lat] }];
|
const vehicles = [{ id: 0, start: [waypoints[0].coordinate.lng, waypoints[0].coordinate.lat] }];
|
||||||
try {
|
try {
|
||||||
const res = await fetch(this.config.baseUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jobs, vehicles }) });
|
const res = await fetch(this.config.baseUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jobs, vehicles }) });
|
||||||
const data = await res.json();
|
const data = await res.json() as VROOMResponse;
|
||||||
if (data.code !== 0) throw new Error(data.error);
|
if (data.code !== 0) throw new Error(data.error ?? 'Unknown VROOM error');
|
||||||
const indices = data.routes[0].steps.filter((s: any) => s.type === 'job').map((s: any) => s.job);
|
const indices = data.routes[0].steps.filter((s) => s.type === 'job').map((s) => s.job!);
|
||||||
return { orderedWaypoints: indices.map((i: number) => waypoints[i]), totalDistance: data.summary.distance, totalDuration: data.summary.duration, estimatedCost: this.estimateCosts(data.summary.distance, data.summary.duration) };
|
return { orderedWaypoints: indices.map((i) => waypoints[i]), totalDistance: data.summary.distance, totalDuration: data.summary.duration, estimatedCost: this.estimateCosts(data.summary.distance, data.summary.duration) };
|
||||||
} catch { return this.nearestNeighbor(waypoints); }
|
} catch { return this.nearestNeighbor(waypoints); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,26 @@
|
||||||
|
|
||||||
import type { Waypoint, Route, RoutingOptions, RoutingServiceConfig, Coordinate, RoutingProfile } from '../types';
|
import type { Waypoint, Route, RoutingOptions, RoutingServiceConfig, Coordinate, RoutingProfile } from '../types';
|
||||||
|
|
||||||
|
// Response types for routing APIs
|
||||||
|
interface OSRMResponse {
|
||||||
|
code: string;
|
||||||
|
message?: string;
|
||||||
|
routes: Array<{
|
||||||
|
distance: number;
|
||||||
|
duration: number;
|
||||||
|
geometry: GeoJSON.LineString;
|
||||||
|
legs: Array<{ distance: number; duration: number }>;
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ValhallaResponse {
|
||||||
|
error?: string;
|
||||||
|
trip: {
|
||||||
|
summary: { length: number; time: number };
|
||||||
|
legs: Array<{ summary: { length: number; time: number } }>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export class RoutingService {
|
export class RoutingService {
|
||||||
private config: RoutingServiceConfig;
|
private config: RoutingServiceConfig;
|
||||||
|
|
||||||
|
|
@ -34,9 +54,9 @@ export class RoutingService {
|
||||||
const url = `${this.config.baseUrl}/trip/v1/driving/${coords}?roundtrip=false&source=first&destination=last`;
|
const url = `${this.config.baseUrl}/trip/v1/driving/${coords}?roundtrip=false&source=first&destination=last`;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(url);
|
const res = await fetch(url);
|
||||||
const data = await res.json();
|
const data = await res.json() as { code: string; waypoints?: Array<{ waypoint_index: number }> };
|
||||||
if (data.code !== 'Ok') return waypoints;
|
if (data.code !== 'Ok' || !data.waypoints) return waypoints;
|
||||||
return data.waypoints.map((wp: { waypoint_index: number }) => waypoints[wp.waypoint_index]);
|
return data.waypoints.map((wp) => waypoints[wp.waypoint_index]);
|
||||||
} catch { return waypoints; }
|
} catch { return waypoints; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,8 +76,8 @@ export class RoutingService {
|
||||||
url.searchParams.set('steps', 'true');
|
url.searchParams.set('steps', 'true');
|
||||||
if (options?.alternatives) url.searchParams.set('alternatives', 'true');
|
if (options?.alternatives) url.searchParams.set('alternatives', 'true');
|
||||||
const res = await fetch(url.toString());
|
const res = await fetch(url.toString());
|
||||||
const data = await res.json();
|
const data = await res.json() as OSRMResponse;
|
||||||
if (data.code !== 'Ok') throw new Error(`OSRM error: ${data.message || data.code}`);
|
if (data.code !== 'Ok') throw new Error(`OSRM error: ${data.message ?? data.code}`);
|
||||||
return this.parseOSRMResponse(data, profile);
|
return this.parseOSRMResponse(data, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,27 +85,27 @@ export class RoutingService {
|
||||||
const costing = profile === 'bicycle' ? 'bicycle' : profile === 'foot' ? 'pedestrian' : 'auto';
|
const costing = profile === 'bicycle' ? 'bicycle' : profile === 'foot' ? 'pedestrian' : 'auto';
|
||||||
const body = { locations: coords.map((c) => ({ lat: c.lat, lon: c.lng })), costing, alternates: options?.alternatives ?? 0 };
|
const body = { locations: coords.map((c) => ({ lat: c.lat, lon: c.lng })), costing, alternates: options?.alternatives ?? 0 };
|
||||||
const res = await fetch(`${this.config.baseUrl}/route`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
const res = await fetch(`${this.config.baseUrl}/route`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
||||||
const data = await res.json();
|
const data = await res.json() as ValhallaResponse;
|
||||||
if (data.error) throw new Error(`Valhalla error: ${data.error}`);
|
if (data.error) throw new Error(`Valhalla error: ${data.error}`);
|
||||||
return this.parseValhallaResponse(data, profile);
|
return this.parseValhallaResponse(data, profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseOSRMResponse(data: any, profile: RoutingProfile): Route {
|
private parseOSRMResponse(data: OSRMResponse, profile: RoutingProfile): Route {
|
||||||
const r = data.routes[0];
|
const r = data.routes[0];
|
||||||
return {
|
return {
|
||||||
id: `route-${Date.now()}`, waypoints: [], geometry: r.geometry, profile,
|
id: `route-${Date.now()}`, waypoints: [], geometry: r.geometry, profile,
|
||||||
summary: { distance: r.distance, duration: r.duration },
|
summary: { distance: r.distance, duration: r.duration },
|
||||||
legs: r.legs.map((leg: any, i: number) => ({ startWaypoint: `wp-${i}`, endWaypoint: `wp-${i + 1}`, distance: leg.distance, duration: leg.duration, geometry: { type: 'LineString', coordinates: [] } })),
|
legs: r.legs.map((leg, i) => ({ startWaypoint: `wp-${i}`, endWaypoint: `wp-${i + 1}`, distance: leg.distance, duration: leg.duration, geometry: { type: 'LineString' as const, coordinates: [] } })),
|
||||||
alternatives: data.routes.slice(1).map((alt: any) => this.parseOSRMResponse({ routes: [alt] }, profile)),
|
alternatives: data.routes.slice(1).map((alt) => this.parseOSRMResponse({ code: 'Ok', routes: [alt] }, profile)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseValhallaResponse(data: any, profile: RoutingProfile): Route {
|
private parseValhallaResponse(data: ValhallaResponse, profile: RoutingProfile): Route {
|
||||||
const trip = data.trip;
|
const trip = data.trip;
|
||||||
return {
|
return {
|
||||||
id: `route-${Date.now()}`, waypoints: [], geometry: { type: 'LineString', coordinates: [] }, profile,
|
id: `route-${Date.now()}`, waypoints: [], geometry: { type: 'LineString' as const, coordinates: [] }, profile,
|
||||||
summary: { distance: trip.summary.length * 1000, duration: trip.summary.time },
|
summary: { distance: trip.summary.length * 1000, duration: trip.summary.time },
|
||||||
legs: trip.legs.map((leg: any, i: number) => ({ startWaypoint: `wp-${i}`, endWaypoint: `wp-${i + 1}`, distance: leg.summary.length * 1000, duration: leg.summary.time, geometry: { type: 'LineString', coordinates: [] } })),
|
legs: trip.legs.map((leg, i) => ({ startWaypoint: `wp-${i}`, endWaypoint: `wp-${i + 1}`, distance: leg.summary.length * 1000, duration: leg.summary.time, geometry: { type: 'LineString' as const, coordinates: [] } })),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,9 @@
|
||||||
},
|
},
|
||||||
"include": ["src", "worker", "src/client"],
|
"include": ["src", "worker", "src/client"],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"src/open-mapping/**"
|
"src/open-mapping/discovery/**",
|
||||||
|
"src/open-mapping/components/CollaborativeMap.tsx",
|
||||||
|
"src/open-mapping/components/MapCanvas.tsx"
|
||||||
],
|
],
|
||||||
"references": [{ "path": "./tsconfig.node.json" }]
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue