import * as _ from "lodash" ; import { CoreEnv } from "../../config/core-env" ; import { VacuumProcessor } from "./vacuum-processor" ; import { LatLonSpherical } from "geodesy" ; export interface ISegmentInfo { id : number ; name : string ; climb_category : number ; climb_category_desc : number ; avg_grade : number ; start_latlng : number [ ] ; end_latlng : number [ ] ; elev_difference : number ; distance : number ; type : string ; } export class SegmentProcessor { public static cachePrefix = "elevate_nearbySegments_" ; protected vacuumProcessor : VacuumProcessor ; protected segmentId : number ; constructor ( vacuumProcessor , segmentId ) { this . vacuumProcessor = vacuumProcessor ; this . segmentId = segmentId ; } public getNearbySegmentsAround ( callback ) { const cacheResult = JSON . parse ( localStorage . getItem ( SegmentProcessor . cachePrefix + this . segmentId ) ) ; if ( ! _ . isNull ( cacheResult ) && ! CoreEnv . debugMode ) { if ( CoreEnv . debugMode ) { console . log ( "Using existing nearbySegments cache in non debug mode: " + JSON . stringify ( cacheResult ) ) ; } callback ( cacheResult ) ; return ; } this . getSegmentAroundSearchPoint ( ( searchPoint ) => { const boundingBox = this . getBoundingBox ( searchPoint , 2000 ) ; this . getSegmentsInBoundingBox ( boundingBox , ( segmentsInBounds ) => { if ( CoreEnv . debugMode ) { console . log ( "Creating nearbySegments cache: " + JSON . stringify ( segmentsInBounds ) ) ; } try { localStorage . setItem ( SegmentProcessor . cachePrefix + this . segmentId , JSON . stringify ( segmentsInBounds ) ) ; } catch ( err ) { console . warn ( err ) ; localStorage . clear ( ) ; } callback ( segmentsInBounds ) ; } ) ; } ) ; } public getBoundingBox ( point , distance ) { return [ point . destinationPoint ( distance , 180 ) . lat , point . destinationPoint ( distance , - 90 ) . lon , point . destinationPoint ( distance , 0 ) . lat , point . destinationPoint ( distance , 90 ) . lon , ] ; } public getSegmentsInBoundingBox ( boundingBox , callback ) { this . vacuumProcessor . getSegmentsFromBounds ( boundingBox [ 0 ] + "," + boundingBox [ 1 ] , boundingBox [ 2 ] + "," + boundingBox [ 3 ] , ( segmentsData ) => { _ . forEach ( segmentsData . cycling . segments , ( segment ) => { segment . type = "cycling" ; } ) ; _ . forEach ( segmentsData . running . segments , ( segment ) => { segment . type = "running" ; } ) ; segmentsData = _ . union ( segmentsData . cycling . segments , segmentsData . running . segments ) ; segmentsData = _ . filter ( segmentsData , ( segment ) => { return ( segment . id !== this . segmentId ) ; } ) ; callback ( segmentsData ) ; } ) ; } public getSegmentAroundSearchPoint ( callback ) { this . vacuumProcessor . getSegmentStream ( this . segmentId , ( stream ) => { const startPoint = stream . latlng [ 0 ] ; const midPoint = stream . latlng [ ( stream . latlng . length / 2 ) . toFixed ( 0 ) ] ; const endPoint = stream . latlng [ stream . latlng . length - 1 ] ; const approximateSearchPoint = [ null , null ] ; approximateSearchPoint [ 0 ] = ( startPoint [ 0 ] + endPoint [ 0 ] ) / 2 ; approximateSearchPoint [ 1 ] = ( startPoint [ 1 ] + endPoint [ 1 ] ) / 2 ; approximateSearchPoint [ 0 ] = ( approximateSearchPoint [ 0 ] + midPoint [ 0 ] ) / 2 ; approximateSearchPoint [ 1 ] = ( approximateSearchPoint [ 1 ] + midPoint [ 1 ] ) / 2 ; callback ( new LatLonSpherical ( approximateSearchPoint [ 0 ] , approximateSearchPoint [ 1 ] ) ) ; } ) ; } }