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({
|
||||
layers,
|
||||
onLayerToggle,
|
||||
onLayerOpacity,
|
||||
onLayerReorder,
|
||||
onLayerAdd,
|
||||
onLayerRemove,
|
||||
onLayerEdit,
|
||||
onLayerOpacity: _onLayerOpacity,
|
||||
onLayerReorder: _onLayerReorder,
|
||||
onLayerAdd: _onLayerAdd,
|
||||
onLayerRemove: _onLayerRemove,
|
||||
onLayerEdit: _onLayerEdit,
|
||||
}: LayerPanelProps) {
|
||||
// Suppress unused variable warnings for future implementation
|
||||
void _onLayerOpacity;
|
||||
void _onLayerReorder;
|
||||
void _onLayerAdd;
|
||||
void _onLayerRemove;
|
||||
void _onLayerEdit;
|
||||
// TODO: Implement layer panel UI
|
||||
// This will be implemented in Phase 2
|
||||
|
||||
|
|
|
|||
|
|
@ -34,16 +34,25 @@ const DEFAULT_PROFILE_COLORS: Record<RoutingProfile, string> = {
|
|||
};
|
||||
|
||||
export function RouteLayer({
|
||||
routes,
|
||||
selectedRouteId,
|
||||
showAlternatives = true,
|
||||
showElevation = false,
|
||||
onRouteSelect,
|
||||
onRouteEdit,
|
||||
routes: _routes,
|
||||
selectedRouteId: _selectedRouteId,
|
||||
showAlternatives: _showAlternatives = true,
|
||||
showElevation: _showElevation = false,
|
||||
onRouteSelect: _onRouteSelect,
|
||||
onRouteEdit: _onRouteEdit,
|
||||
profileColors = {},
|
||||
}: RouteLayerProps) {
|
||||
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
|
||||
// This will be implemented in Phase 2
|
||||
|
||||
|
|
|
|||
|
|
@ -23,20 +23,10 @@ interface WaypointMarkerProps {
|
|||
onDelete?: (waypointId: string) => void;
|
||||
}
|
||||
|
||||
export function WaypointMarker({
|
||||
waypoint,
|
||||
index,
|
||||
isSelected = false,
|
||||
isDraggable = true,
|
||||
showLabel = true,
|
||||
showTime = false,
|
||||
showBudget = false,
|
||||
onSelect,
|
||||
onDragEnd,
|
||||
onDelete,
|
||||
}: WaypointMarkerProps) {
|
||||
export function WaypointMarker(_props: WaypointMarkerProps) {
|
||||
// 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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -636,3 +636,81 @@ function findOrthogonalVector(v: SpaceVector): SpaceVector {
|
|||
|
||||
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 {
|
||||
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: string[];
|
||||
|
||||
/** Source constraints (for combined cones) */
|
||||
sourceConstraints?: string[];
|
||||
|
||||
/** Metadata */
|
||||
metadata: Record<string, unknown>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -427,3 +427,16 @@ export function precisionForRadius(radiusMeters: number): number {
|
|||
}
|
||||
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
|
||||
*/
|
||||
|
||||
// Re-export GeohashPrecision so consumers can import from types
|
||||
export type { GeohashPrecision } from './geohash';
|
||||
import type { GeohashPrecision } from './geohash';
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -49,6 +51,9 @@ export interface LocationCommitment {
|
|||
|
||||
/** Optional: the geohash prefix that is publicly revealed */
|
||||
revealedPrefix?: string;
|
||||
|
||||
/** The geohash string (at the given precision) */
|
||||
geohash?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -72,6 +77,11 @@ export interface SignedCommitment extends LocationCommitment {
|
|||
signerPublicKey: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for LocationCommitment (used by discovery module)
|
||||
*/
|
||||
export type GeohashCommitment = LocationCommitment;
|
||||
|
||||
// =============================================================================
|
||||
// Trust Circle Types
|
||||
// =============================================================================
|
||||
|
|
|
|||
|
|
@ -4,6 +4,16 @@
|
|||
|
||||
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 {
|
||||
orderedWaypoints: Waypoint[];
|
||||
totalDistance: number;
|
||||
|
|
@ -50,10 +60,10 @@ export class OptimizationService {
|
|||
const vehicles = [{ id: 0, start: [waypoints[0].coordinate.lng, waypoints[0].coordinate.lat] }];
|
||||
try {
|
||||
const res = await fetch(this.config.baseUrl, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ jobs, vehicles }) });
|
||||
const data = await res.json();
|
||||
if (data.code !== 0) throw new Error(data.error);
|
||||
const indices = data.routes[0].steps.filter((s: any) => s.type === 'job').map((s: any) => 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) };
|
||||
const data = await res.json() as VROOMResponse;
|
||||
if (data.code !== 0) throw new Error(data.error ?? 'Unknown VROOM error');
|
||||
const indices = data.routes[0].steps.filter((s) => s.type === 'job').map((s) => s.job!);
|
||||
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); }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,26 @@
|
|||
|
||||
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 {
|
||||
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`;
|
||||
try {
|
||||
const res = await fetch(url);
|
||||
const data = await res.json();
|
||||
if (data.code !== 'Ok') return waypoints;
|
||||
return data.waypoints.map((wp: { waypoint_index: number }) => waypoints[wp.waypoint_index]);
|
||||
const data = await res.json() as { code: string; waypoints?: Array<{ waypoint_index: number }> };
|
||||
if (data.code !== 'Ok' || !data.waypoints) return waypoints;
|
||||
return data.waypoints.map((wp) => waypoints[wp.waypoint_index]);
|
||||
} catch { return waypoints; }
|
||||
}
|
||||
|
||||
|
|
@ -56,8 +76,8 @@ export class RoutingService {
|
|||
url.searchParams.set('steps', 'true');
|
||||
if (options?.alternatives) url.searchParams.set('alternatives', 'true');
|
||||
const res = await fetch(url.toString());
|
||||
const data = await res.json();
|
||||
if (data.code !== 'Ok') throw new Error(`OSRM error: ${data.message || data.code}`);
|
||||
const data = await res.json() as OSRMResponse;
|
||||
if (data.code !== 'Ok') throw new Error(`OSRM error: ${data.message ?? data.code}`);
|
||||
return this.parseOSRMResponse(data, profile);
|
||||
}
|
||||
|
||||
|
|
@ -65,27 +85,27 @@ export class RoutingService {
|
|||
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 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}`);
|
||||
return this.parseValhallaResponse(data, profile);
|
||||
}
|
||||
|
||||
private parseOSRMResponse(data: any, profile: RoutingProfile): Route {
|
||||
private parseOSRMResponse(data: OSRMResponse, profile: RoutingProfile): Route {
|
||||
const r = data.routes[0];
|
||||
return {
|
||||
id: `route-${Date.now()}`, waypoints: [], geometry: r.geometry, profile,
|
||||
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: [] } })),
|
||||
alternatives: data.routes.slice(1).map((alt: any) => this.parseOSRMResponse({ routes: [alt] }, profile)),
|
||||
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) => 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;
|
||||
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 },
|
||||
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"],
|
||||
"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" }]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue