├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ ├── maven.yml │ └── package.yml ├── .gitignore ├── COMPLIANCE.yaml ├── Dockerfile ├── LICENSE ├── ols-router-admin ├── pom.xml └── src │ └── main │ ├── java │ └── ca │ │ └── bc │ │ └── gov │ │ └── ols │ │ └── router │ │ └── admin │ │ ├── AdminApplication.java │ │ ├── AdminController.java │ │ └── WebConfig.java │ └── webapp │ ├── WEB-INF │ └── view │ │ ├── import.jsp │ │ └── validate.jsp │ ├── css │ └── styles.css │ ├── footer.jsp │ ├── header.jsp │ ├── help.jsp │ ├── import_export.jsp │ ├── index.jsp │ └── params.jsp ├── ols-router-core ├── pom.xml └── src │ ├── main │ ├── java │ │ └── ca │ │ │ └── bc │ │ │ └── gov │ │ │ └── ols │ │ │ └── router │ │ │ ├── Router.java │ │ │ ├── RouterFactory.java │ │ │ ├── RoutingEngine.java │ │ │ ├── api │ │ │ ├── ApiResponse.java │ │ │ ├── DefaultsResponse.java │ │ │ ├── GeometryReprojector.java │ │ │ ├── IsochroneResponse.java │ │ │ ├── NavInfoParameters.java │ │ │ ├── NavInfoResponse.java │ │ │ ├── RouterDirectionsResponse.java │ │ │ ├── RouterDistanceBetweenPairsResponse.java │ │ │ ├── RouterDistanceResponse.java │ │ │ ├── RouterOptimalDirectionsResponse.java │ │ │ ├── RouterOptimalRouteResponse.java │ │ │ ├── RouterOptimizedResponse.java │ │ │ ├── RouterRouteResponse.java │ │ │ ├── RoutingParameters.java │ │ │ └── TurnRestrictionVis.java │ │ │ ├── config │ │ │ ├── InMemoryRouterConfigurationStore.java │ │ │ ├── RouterConfig.java │ │ │ └── RouterConfigurationStoreFactory.java │ │ │ ├── data │ │ │ ├── RoadClosureEvent.java │ │ │ ├── RoadDelayEvent.java │ │ │ ├── RoadEvent.java │ │ │ ├── RoadTruckNoticeEvent.java │ │ │ ├── StreetIntersection.java │ │ │ ├── StreetSegment.java │ │ │ ├── TurnClass.java │ │ │ ├── TurnRestriction.java │ │ │ ├── WeeklyTimeRange.java │ │ │ ├── enums │ │ │ │ ├── DayCode.java │ │ │ │ ├── DistanceUnit.java │ │ │ │ ├── End.java │ │ │ │ ├── NavInfoType.java │ │ │ │ ├── RestrictionSource.java │ │ │ │ ├── RestrictionType.java │ │ │ │ ├── RouteOption.java │ │ │ │ ├── RoutingCriteria.java │ │ │ │ ├── TruckNoticeType.java │ │ │ │ ├── TurnDirection.java │ │ │ │ ├── TurnRestrictionType.java │ │ │ │ ├── TurnTimeCode.java │ │ │ │ ├── VehicleType.java │ │ │ │ └── XingClass.java │ │ │ └── vis │ │ │ │ ├── VisFeature.java │ │ │ │ ├── VisLayer.java │ │ │ │ ├── VisLayers.java │ │ │ │ └── VisTurnRestriction.java │ │ │ ├── datasource │ │ │ ├── DataUpdateManager.java │ │ │ ├── FileRouterDataSource.java │ │ │ ├── RouterDataLoader.java │ │ │ ├── RouterDataSource.java │ │ │ ├── RouterDataSourceFactory.java │ │ │ └── TestDataSource.java │ │ │ ├── directions │ │ │ ├── AbstractTravelDirection.java │ │ │ ├── CardinalDirection.java │ │ │ ├── Direction.java │ │ │ ├── FerryDirection.java │ │ │ ├── FinishDirection.java │ │ │ ├── LaneRequirement.java │ │ │ ├── Partition.java │ │ │ ├── StartDirection.java │ │ │ ├── StopoverDirection.java │ │ │ ├── StreetDirection.java │ │ │ └── StreetDirectionType.java │ │ │ ├── engine │ │ │ ├── GraphBuilder.java │ │ │ ├── basic │ │ │ │ ├── Attribute.java │ │ │ │ ├── BasicGraph.java │ │ │ │ ├── BasicGraphBuilder.java │ │ │ │ ├── BasicGraphInternal.java │ │ │ │ ├── BasicGraphRoutingEngine.java │ │ │ │ ├── CostFunction.java │ │ │ │ ├── DijkstraShortestPath.java │ │ │ │ ├── DijkstraWalker.java │ │ │ │ ├── EdgeList.java │ │ │ │ ├── EdgeMerger.java │ │ │ │ ├── EventLookup.java │ │ │ │ ├── FerryInfo.java │ │ │ │ ├── GlobalDistortionField.java │ │ │ │ ├── QueryGraph.java │ │ │ │ ├── ScheduleLookup.java │ │ │ │ ├── SegmentIdLookup.java │ │ │ │ ├── SplitEdge.java │ │ │ │ ├── TrafficLookup.java │ │ │ │ ├── TrafficLookupBuilder.java │ │ │ │ ├── TurnLookup.java │ │ │ │ └── WayPoint.java │ │ │ └── graphhopper │ │ │ │ ├── GraphHopperCoordinateSequence.java │ │ │ │ ├── GraphHopperGraphBuilder.java │ │ │ │ ├── GraphHopperRoutingEngine.java │ │ │ │ ├── Isochrone.java │ │ │ │ ├── ParallelDijkstra.java │ │ │ │ ├── RouterGraphHopper.java │ │ │ │ └── isochrone │ │ │ │ ├── ContourBuilder.java │ │ │ │ └── RasterHullBuilder.java │ │ │ ├── notifications │ │ │ ├── EventWaitNotification.java │ │ │ ├── FerryWaitNotification.java │ │ │ ├── Notification.java │ │ │ ├── OversizeNotification.java │ │ │ └── TruckNotification.java │ │ │ ├── open511 │ │ │ ├── Area.java │ │ │ ├── Event.java │ │ │ ├── EventResponse.java │ │ │ ├── LocalTimeInterval.java │ │ │ ├── Meta.java │ │ │ ├── Pagination.java │ │ │ ├── RecurringSchedule.java │ │ │ ├── Restriction.java │ │ │ ├── Road.java │ │ │ ├── Schedule.java │ │ │ ├── ScheduleInterval.java │ │ │ ├── enums │ │ │ │ ├── Direction.java │ │ │ │ ├── EventCertainty.java │ │ │ │ ├── EventSeverity.java │ │ │ │ ├── EventStatus.java │ │ │ │ ├── EventSubtype.java │ │ │ │ ├── EventType.java │ │ │ │ ├── ImpactedSystem.java │ │ │ │ ├── Open511RestrictionType.java │ │ │ │ ├── RoadState.java │ │ │ │ └── ScheduleException.java │ │ │ └── parser │ │ │ │ └── Open511Parser.java │ │ │ ├── restrictions │ │ │ ├── AbstractRestriction.java │ │ │ ├── Constraint.java │ │ │ ├── LaneBasedRestriction.java │ │ │ ├── RestrictionLookup.java │ │ │ ├── RestrictionLookupBuilder.java │ │ │ └── rdm │ │ │ │ ├── RdmFetcher.java │ │ │ │ ├── RdmParser.java │ │ │ │ ├── Restriction.java │ │ │ │ └── RestrictionBuilder.java │ │ │ ├── status │ │ │ ├── BasicStatusMessage.java │ │ │ ├── RdmStatusMessage.java │ │ │ ├── StatusMessage.java │ │ │ └── SystemStatus.java │ │ │ ├── time │ │ │ ├── Always.java │ │ │ ├── DateInterval.java │ │ │ ├── DaySet.java │ │ │ ├── TemporalSet.java │ │ │ ├── TemporalSetIntersection.java │ │ │ ├── TemporalSetUnion.java │ │ │ └── WeeklyDateRange.java │ │ │ └── util │ │ │ ├── Azimuth.java │ │ │ ├── GeomParseUtil.java │ │ │ ├── TimeHelper.java │ │ │ └── UrlCsvInputSource.java │ ├── resources-filtered │ │ └── app.properties │ └── resources │ │ ├── bgeo_configuration_parameters.csv │ │ └── logback.xml │ └── test │ └── java │ └── ca │ └── bc │ └── gov │ └── ols │ └── router │ └── util │ └── AzimuthTest.java ├── ols-router-process ├── pom.xml └── src │ └── main │ └── java │ └── ca │ └── bc │ └── gov │ └── ols │ └── router │ ├── process │ ├── RouterProcess.java │ ├── RpStreetEnd.java │ ├── RpStreetIntersection.java │ └── RpStreetSegment.java │ └── rdm │ └── RdmFetcher.java ├── ols-router-web ├── pom.xml └── src │ ├── main │ └── java │ │ └── ca │ │ └── bc │ │ └── gov │ │ └── ols │ │ └── router │ │ └── rest │ │ ├── GeotoolsGeometryReprojector.java │ │ ├── RouterApplication.java │ │ ├── SpringSecurityInitializer.java │ │ ├── ThreadPoolTaskSchedulerConfig.java │ │ ├── WebConfig.java │ │ ├── WebSecurityConfig.java │ │ ├── controllers │ │ └── RoutingController.java │ │ ├── converters │ │ ├── BooleanConverter.java │ │ ├── DistanceUnitConverter.java │ │ ├── InstantConverter.java │ │ └── RoutingCriteriaConverter.java │ │ ├── exceptions │ │ ├── ErrorMessage.java │ │ ├── ExceptionMapper.java │ │ ├── InvalidParameterException.java │ │ └── NotFoundException.java │ │ └── messageconverters │ │ ├── ConverterHelper.java │ │ ├── html │ │ ├── HtmlConverterHelper.java │ │ ├── HtmlErrorMessageConverter.java │ │ └── HtmlResponseConverter.java │ │ ├── json │ │ ├── JsonConverterHelper.java │ │ ├── JsonDefaultsResponseConverter.java │ │ ├── JsonNavInfoResponseConverter.java │ │ ├── JsonResponseConverter.java │ │ ├── JsonpConverterHelper.java │ │ └── JsonpResponseConverter.java │ │ └── kml │ │ ├── KmlConverterHelper.java │ │ ├── KmlErrorMessageConverter.java │ │ └── KmlResponseConverter.java │ └── test │ └── java │ └── ca │ └── bc │ └── gov │ └── ols │ └── router │ └── rest │ └── controllers │ └── RoutingControllerTest.java ├── pom.xml ├── readme.md └── src ├── assembly └── license-header.xml └── license ├── THIRD-PARTY.txt └── license-header.txt /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: GitHub CI for Router 2 | 3 | on: 4 | push: 5 | branches: 6 | - dev 7 | pull_request: 8 | branches: 9 | - master 10 | - dev 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: ${{ matrix.os }} 16 | strategy: 17 | matrix: 18 | java_version: [1.11] 19 | os: [ubuntu-latest] 20 | pom_ver: [2.0.0] 21 | 22 | steps: 23 | - name: SCM Checkout 24 | uses: actions/checkout@v1 25 | - name: Set up JDK 11 26 | uses: actions/setup-java@v1 27 | with: 28 | java-version: ${{ matrix.java_version }} 29 | - name: Update Maven Release Version 30 | run: mvn versions:set -DnewVersion='${{ matrix.pom_ver }}' -DgenerateBackupPoms=false --file pom.xml 31 | - name: Build with Maven and Scan with SonarQube 32 | env: 33 | SONAR_URL: ${{ secrets.SONAR_URL }} 34 | SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} 35 | run: mvn clean package sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_TOKEN --file pom.xml 36 | # - uses: 8398a7/action-slack@v1 37 | # with: 38 | # type: failure 39 | # env: 40 | # SLACK_WEBHOOK_URL: ${{ secrets.MM_WEBHOOK }} 41 | # GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 42 | # if: failure() 43 | # - uses: 8398a7/action-slack@v1 44 | # with: 45 | # type: success 46 | # env: 47 | # SLACK_WEBHOOK_URL: ${{ secrets.MM_WEBHOOK }} 48 | # GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} 49 | # if: success() 50 | -------------------------------------------------------------------------------- /.github/workflows/package.yml: -------------------------------------------------------------------------------- 1 | name: sidecar package 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | dockerize: 8 | runs-on: ${{ matrix.os }} 9 | strategy: 10 | matrix: 11 | os: [ubuntu-latest] 12 | steps: 13 | - name: SCM Checkout 14 | uses: actions/checkout@v1 15 | - name: One Click Docker 16 | uses: pangzineng/Github-Action-One-Click-Docker@v1.1.1 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ---> Java 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # Maven 26 | target/ 27 | 28 | # Eclipse 29 | .project 30 | .metadata 31 | .factorypath 32 | bin/** 33 | tmp/** 34 | tmp/**/* 35 | *.tmp 36 | *.bak 37 | *.swp 38 | local.properties 39 | .classpath 40 | .settings/ 41 | .loadpath 42 | *.launch 43 | 44 | # IntelliJ 45 | 46 | .idea/ 47 | *.iml 48 | -------------------------------------------------------------------------------- /COMPLIANCE.yaml: -------------------------------------------------------------------------------- 1 | name: compliance 2 | description: | 3 | This document is used to track a projects PIA and STRA 4 | compliance. 5 | spec: 6 | - name: PIA 7 | status: PIA_STATUS_HERE 8 | last-updated: '2020-01-17T00:09:23.449Z' 9 | - name: STRA 10 | status: STRA_STATUS_HERE 11 | last-updated: '2020-01-17T00:09:23.449Z' 12 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM maven:3-jdk-11-slim AS builder 2 | ADD . /app 3 | WORKDIR /app 4 | RUN mvn versions:set -DnewVersion='1' -DgenerateBackupPoms=false && mvn package 5 | 6 | FROM busybox 7 | RUN mkdir /app 8 | COPY --from=builder /app/ols-*/target/ols-*.war /app/ 9 | RUN ls -la /app/ 10 | CMD ["tail", "-f", "/dev/null"] 11 | -------------------------------------------------------------------------------- /ols-router-admin/src/main/java/ca/bc/gov/ols/router/admin/AdminApplication.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.admin; 2 | 3 | import javax.annotation.PreDestroy; 4 | 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.boot.SpringApplication; 8 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; 11 | import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; 12 | 13 | import ca.bc.gov.ols.config.ConfigurationStore; 14 | import ca.bc.gov.ols.router.RouterFactory; 15 | import ca.bc.gov.ols.router.config.RouterConfigurationStoreFactory; 16 | 17 | @SpringBootApplication 18 | @EnableAutoConfiguration(exclude={CassandraAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class}) 19 | public class AdminApplication { 20 | 21 | static final Logger logger = LoggerFactory.getLogger( 22 | AdminApplication.class.getCanonicalName()); 23 | 24 | private static AdminApplication singleton; 25 | 26 | private ConfigurationStore configStore; 27 | 28 | public static void main(String[] args) { 29 | SpringApplication.run(AdminApplication.class, args); 30 | } 31 | 32 | public AdminApplication() { 33 | logger.info("AdminApplication() constructor called"); 34 | configStore = RouterConfigurationStoreFactory.getConfigurationStore(RouterFactory.getBootstrapConfigFromEnvironment()); 35 | singleton = this; 36 | } 37 | 38 | public static AdminApplication adminApplication() { 39 | if(singleton == null) { 40 | singleton = new AdminApplication(); 41 | } 42 | return singleton; 43 | } 44 | 45 | public ConfigurationStore getConfigStore() { 46 | return configStore; 47 | } 48 | 49 | @PreDestroy 50 | public void preDestroy() { 51 | configStore.close(); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /ols-router-admin/src/main/java/ca/bc/gov/ols/router/admin/WebConfig.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.admin; 2 | 3 | import org.apache.catalina.Context; 4 | import org.apache.tomcat.util.scan.StandardJarScanner; 5 | import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 9 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 10 | import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; 11 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 12 | 13 | @Configuration 14 | @EnableWebMvc 15 | public class WebConfig implements WebMvcConfigurer { 16 | 17 | @Override 18 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 19 | registry 20 | .addResourceHandler("/css/**") 21 | .addResourceLocations("/css/"); 22 | } 23 | 24 | @Override 25 | public void configureViewResolvers(ViewResolverRegistry registry) { 26 | registry.jsp(); 27 | } 28 | 29 | // prevents tomcat from scanning every library jar's manifest 30 | @Bean 31 | public TomcatServletWebServerFactory tomcatFactory() { 32 | return new TomcatServletWebServerFactory() { 33 | @Override 34 | protected void postProcessContext(Context context) { 35 | ((StandardJarScanner) context.getJarScanner()).setScanManifest(false); 36 | } 37 | }; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ols-router-admin/src/main/webapp/WEB-INF/view/import.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | 3 | Copyright 2008-2015, Province of British Columbia 4 | All rights reserved. 5 | 6 | --%> 7 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 8 | <%@ include file="../../header.jsp" %> 9 |
10 |

Import Configuration

11 | 12 | 13 |

Import Failed

14 |

Errors

15 |
    16 | 17 |
  • ${error}
  • 18 |
    19 |
20 |
21 | 22 |

Import Successful

23 |
24 |
25 | 26 |

Messages

27 | 32 |
33 |
34 | <%@ include file="../../footer.jsp" %> -------------------------------------------------------------------------------- /ols-router-admin/src/main/webapp/WEB-INF/view/validate.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | 3 | Copyright 2008-2015, Province of British Columbia 4 | All rights reserved. 5 | 6 | --%> 7 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 8 | <%@ include file="../../header.jsp" %> 9 |
10 |

Validate Configuration

11 |

File Name: ${exportConfig.fileName}

12 |

Export Date (from file contents): ${exportConfig.exportDate}

13 | 14 | 15 |

Validation Failed

16 |

Errors

17 |
    18 | 19 |
  • ${error}
  • 20 |
    21 |
22 |
23 | 24 |

Validation Successful

25 |
26 |
27 | 28 |

Messages

29 | 34 |
35 |

Record Counts

36 | 37 | 38 | 39 |
TableLive Config RecordsFile RecordsFile Check Count
Configuration Parameters${comparison.curConfigParamCount}${comparison.otherConfigParamCount}${exportConfig.configParamCount}
40 |

Comparison with Live Config

41 |

Configuration Parameters Differences

42 | 43 | 44 |

No Differences

45 |
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 |
Live ConfigFile
APP_IDCONFIG_PARAM_NAMECONFIG_PARAM_VALUEAPP_IDCONFIG_PARAM_NAMECONFIG_PARAM_VALUE
Not Present${diff.current.appId}${diff.current.configParamName}${diff.current.configParamValue}Not Present${diff.other.appId}${diff.other.configParamName}${diff.other.configParamValue}
72 |
73 |
74 | 75 |
76 | 77 | <%@ include file="../../footer.jsp" %> -------------------------------------------------------------------------------- /ols-router-admin/src/main/webapp/footer.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | 3 | Copyright 2008-2015, Province of British Columbia 4 | All rights reserved. 5 | 6 | --%> 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ols-router-admin/src/main/webapp/header.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | 3 | Copyright 2008-2015, Province of British Columbia 4 | All rights reserved. 5 | 6 | --%> 7 | 8 | 9 | 10 | OLS Router Admin 11 | 12 | 13 | 14 |
15 | 27 |
-------------------------------------------------------------------------------- /ols-router-admin/src/main/webapp/help.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | 3 | Copyright 2008-2015, Province of British Columbia 4 | All rights reserved. 5 | 6 | --%> 7 | <%@ include file="header.jsp" %> 8 |
9 |

Location Services Administration Help

10 |

General Information

11 |

For all of the editable values you can change through this Admin Interface, they will be change in the database configuration tables. This will not update any existing, running services. Restarting Tomcat and reloading the CPF plug-in will be required before the parameters are used in the live services. This is because the services have all the required configuration in memory and do not interact with the configuration database on a live basis for performance reasons.

12 |

Parameter Defaults Page

13 | 14 |

There are a number of general parameters that can be edited using this page. To edit them simply change the field values and press 'Save all Values'. 15 | 16 |

apiUrl

17 |

The URL to the API documentation.

18 | 19 |

copyrightLicense

20 |

The URL link to the copyright license information.

21 | 22 |

copyrightNotice

23 |

The text of the copyright notice.

24 | 25 |

defaultLookAtRange

26 |

The default lookAtRange for KML output

27 | 28 |

defaultSetBack

29 |

This parameter is used once a geocoded point has been found. The setback is the perpendicular distance from the road centerline the final returned co-ordinate will be, in meters.

30 | 31 |

disclaimer

32 |

The URL link to the disclaimer information.

33 | 34 |

glossaryBaseURL

35 |

.The Base URL of the documentation glossary file.

36 | 37 |

kmlStylesUrl

38 |

The url where the kml styles are located.

39 | 40 |

moreInfoURL

41 |

The URL link to the documentation.

42 | 43 |

privacyStatement

44 |

The URL link to the privacy statement

45 | 46 |
47 | <%@ include file="footer.jsp" %> -------------------------------------------------------------------------------- /ols-router-admin/src/main/webapp/import_export.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | 3 | Copyright 2008-2015, Province of British Columbia 4 | All rights reserved. 5 | 6 | --%> 7 | <%@ include file="header.jsp"%> 8 | 23 |
24 |

Export Configuration

25 |
26 |

27 |
28 |


29 |

Validate Configuration

30 |
31 |

32 | 33 | 34 |

35 |
36 |


37 |

Import Configuration

38 |
40 |

41 | 42 | 43 |

44 |
45 |
46 | 47 | <%@ include file="footer.jsp" %> 48 | -------------------------------------------------------------------------------- /ols-router-admin/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | 3 | Copyright 2008-2015, Province of British Columbia 4 | All rights reserved. 5 | 6 | --%> 7 | <%@ include file="header.jsp" %> 8 |
9 |

OLS Router Administration

10 |
11 | <%@ include file="footer.jsp" %> -------------------------------------------------------------------------------- /ols-router-admin/src/main/webapp/params.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | 3 | Copyright 2008-2015, Province of British Columbia 4 | All rights reserved. 5 | 6 | --%> 7 | <%@ page language="java" import="ca.bc.gov.ols.router.admin.AdminApplication" %> 8 | <%@ page language="java" import="ca.bc.gov.ols.config.ConfigurationStore" %> 9 | <%@ page language="java" import="ca.bc.gov.ols.config.ConfigurationParameter" %> 10 | <%@ page language="java" import="java.util.List" %> 11 | <%@ page language="java" import="java.util.stream.Collectors" %> 12 | <%@ page language="java" import="java.util.Collections" %> 13 | <%@ page language="java" import="java.util.Comparator" %> 14 | 15 | <%@ include file="header.jsp"%> 16 | 17 | <% 18 | AdminApplication adminApp = AdminApplication.adminApplication(); 19 | ConfigurationStore configStore = adminApp.getConfigStore(); 20 | List params = configStore.getConfigParams().collect(Collectors.toList()); 21 | 22 | if(request.getParameter("submitBtn") != null && !request.getParameter("submitBtn").isEmpty()){ 23 | 24 | for (ConfigurationParameter param : params) { 25 | String paramName = param.getConfigParamName(); 26 | param.setConfigParamValue(request.getParameter(paramName)); 27 | configStore.setConfigParam(param); 28 | } 29 | 30 | out.println("

Parameters Saved Successfully, click here to make more changes."); 31 | } else { 32 | %> 33 |
34 | 35 |

Router General Parameters

36 | 37 |
38 | 39 | <% 40 | Collections.sort(params); 41 | for(ConfigurationParameter param : params) { 42 | String name = param.getConfigParamName(); 43 | String value = param.getConfigParamValue(); 44 | if(name.startsWith("fault.") || name.startsWith("precision.")) { 45 | continue; 46 | } 47 | out.println(""); 48 | out.println(""); 49 | out.println(""); 50 | out.println(""); 51 | } 52 | %> 53 |
" + name + ":
54 | 55 |

56 | 57 |
58 |
59 |
60 |
61 | <% 62 | } 63 | %> 64 | <%@ include file="footer.jsp" %> -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/RoutingEngine.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router; 6 | 7 | import java.util.List; 8 | 9 | import ca.bc.gov.ols.router.api.IsochroneResponse; 10 | import ca.bc.gov.ols.router.api.NavInfoParameters; 11 | import ca.bc.gov.ols.router.api.NavInfoResponse; 12 | import ca.bc.gov.ols.router.api.RouterDirectionsResponse; 13 | import ca.bc.gov.ols.router.api.RouterDistanceBetweenPairsResponse; 14 | import ca.bc.gov.ols.router.api.RouterDistanceResponse; 15 | import ca.bc.gov.ols.router.api.RouterOptimalDirectionsResponse; 16 | import ca.bc.gov.ols.router.api.RouterOptimalRouteResponse; 17 | import ca.bc.gov.ols.router.api.RouterRouteResponse; 18 | import ca.bc.gov.ols.router.api.RoutingParameters; 19 | import ca.bc.gov.ols.router.datasource.DataUpdateManager; 20 | import ca.bc.gov.ols.router.status.StatusMessage; 21 | import ca.bc.gov.ols.router.status.StatusMessage.Type; 22 | import ca.bc.gov.ols.router.status.SystemStatus; 23 | 24 | public interface RoutingEngine { 25 | 26 | public abstract RouterDistanceResponse distance(RoutingParameters params); 27 | 28 | public abstract RouterRouteResponse route(RoutingParameters params); 29 | 30 | public abstract RouterDirectionsResponse directions(RoutingParameters params); 31 | 32 | public abstract RouterDistanceBetweenPairsResponse distanceBetweenPairs( 33 | RoutingParameters params); 34 | 35 | public abstract RouterOptimalRouteResponse optimalRoute( 36 | RoutingParameters params); 37 | 38 | public abstract RouterOptimalDirectionsResponse optimalDirections( 39 | RoutingParameters params); 40 | 41 | public abstract IsochroneResponse isochrones(RoutingParameters params); 42 | 43 | public abstract IsochroneResponse loop(RoutingParameters params); 44 | 45 | public abstract NavInfoResponse navInfo(NavInfoParameters params); 46 | 47 | public abstract RoutingEngine getUpdatedEngine(DataUpdateManager dum, SystemStatus status); 48 | 49 | public abstract List getMessages(Type type); 50 | 51 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/DefaultsResponse.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.api; 2 | 3 | import java.util.Set; 4 | 5 | import ca.bc.gov.ols.router.config.RouterConfig; 6 | import ca.bc.gov.ols.router.data.enums.RouteOption; 7 | import ca.bc.gov.ols.router.data.enums.VehicleType; 8 | import ca.bc.gov.ols.router.engine.basic.GlobalDistortionField; 9 | 10 | public class DefaultsResponse { 11 | 12 | RouterConfig config; 13 | 14 | public DefaultsResponse(RouterConfig config) { 15 | this.config = config; 16 | } 17 | 18 | public Set getEnabledOptions() { 19 | return RouteOption.fromList(config.getDefaultEnableOptions()); 20 | } 21 | 22 | public GlobalDistortionField getGlobalDistortionField(VehicleType type) { 23 | return new GlobalDistortionField(config.getDefaultGlobalDistortionField(type)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/GeometryReprojector.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import org.locationtech.jts.geom.Geometry; 8 | 9 | public interface GeometryReprojector { 10 | 11 | T reproject(T geom, int toSRSCode); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/IsochroneResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.time.ZonedDateTime; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import org.locationtech.jts.geom.Geometry; 12 | 13 | import ca.bc.gov.ols.rowreader.DateType; 14 | 15 | public class IsochroneResponse extends ApiResponse { 16 | private List polygons; 17 | private int zoneSize = 0; 18 | 19 | public IsochroneResponse(RoutingParameters params, Map dates, List polygons) { 20 | super(params, dates); 21 | this.polygons = polygons; 22 | this.zoneSize = params.getZoneSize(); 23 | } 24 | 25 | public List getPolygons() { 26 | return polygons; 27 | } 28 | 29 | public int getZoneSize() { 30 | return zoneSize; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/NavInfoParameters.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.time.Instant; 8 | import java.util.EnumSet; 9 | import java.util.Set; 10 | 11 | import org.locationtech.jts.geom.Coordinate; 12 | import org.locationtech.jts.geom.Envelope; 13 | import org.locationtech.jts.geom.GeometryFactory; 14 | import org.locationtech.jts.geom.Point; 15 | 16 | import ca.bc.gov.ols.router.config.RouterConfig; 17 | import ca.bc.gov.ols.router.data.enums.NavInfoType; 18 | import ca.bc.gov.ols.router.data.enums.RestrictionSource; 19 | 20 | public class NavInfoParameters { 21 | 22 | private int outputSRS = 4326; 23 | private double[] bbox; 24 | private Envelope envelope; 25 | private Instant departure = Instant.now(); 26 | private RestrictionSource restrictionSource = null; 27 | private Set types = EnumSet.allOf(NavInfoType.class); 28 | 29 | public int getOutputSRS() { 30 | return outputSRS; 31 | } 32 | 33 | public void setOutputSRS(int outputSRS) { 34 | this.outputSRS = outputSRS; 35 | } 36 | 37 | public void setBbox(double[] bbox) { 38 | this.bbox = bbox; 39 | } 40 | 41 | public Envelope getEnvelope() { 42 | return envelope; 43 | } 44 | 45 | public Instant getDeparture() { 46 | return departure; 47 | } 48 | 49 | public void setDeparture(Instant departure) { 50 | if(departure != null) { 51 | this.departure = departure; 52 | } 53 | } 54 | 55 | public RestrictionSource getRestrictionSource() { 56 | return restrictionSource; 57 | } 58 | 59 | public void setRestrictionSource(RestrictionSource restrictionSource) { 60 | this.restrictionSource = restrictionSource; 61 | } 62 | 63 | public Set getTypes() { 64 | return types; 65 | } 66 | 67 | public void setTypes(Set types) { 68 | this.types = types; 69 | } 70 | 71 | public void resolve(RouterConfig config, GeometryFactory gf, GeometryReprojector gr) { 72 | if(bbox != null && bbox.length == 4) { 73 | Point p1 = gr.reproject(gf.createPoint(new Coordinate(bbox[0], bbox[1])), config.getBaseSrsCode()); 74 | Point p2 = gr.reproject(gf.createPoint(new Coordinate(bbox[2], bbox[3])), config.getBaseSrsCode()); 75 | envelope = new Envelope(p1.getCoordinate(), p2.getCoordinate()); 76 | } 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/NavInfoResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.util.List; 8 | 9 | import ca.bc.gov.ols.router.data.vis.VisFeature; 10 | 11 | public class NavInfoResponse { 12 | 13 | private final int srsCode; 14 | private final List geoms; 15 | 16 | public NavInfoResponse(NavInfoParameters params, List geoms) { 17 | srsCode = params.getOutputSRS(); 18 | this.geoms = geoms; 19 | } 20 | 21 | public int getSrsCode() { 22 | return srsCode; 23 | } 24 | 25 | public List getMapGeoms() { 26 | return geoms; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/RouterDirectionsResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.time.ZonedDateTime; 8 | import java.util.Collection; 9 | import java.util.Collections; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | import org.locationtech.jts.geom.LineString; 14 | 15 | import ca.bc.gov.ols.router.data.enums.DistanceUnit; 16 | import ca.bc.gov.ols.router.directions.AbstractTravelDirection; 17 | import ca.bc.gov.ols.router.directions.Direction; 18 | import ca.bc.gov.ols.router.directions.LaneRequirement; 19 | import ca.bc.gov.ols.router.directions.Partition; 20 | import ca.bc.gov.ols.router.notifications.Notification; 21 | import ca.bc.gov.ols.rowreader.DateType; 22 | 23 | public class RouterDirectionsResponse extends RouterRouteResponse { 24 | 25 | private List directions; 26 | private Collection notifications; 27 | 28 | public RouterDirectionsResponse(RoutingParameters params, Map dates) { 29 | super(params, dates); 30 | directions = Collections.emptyList(); 31 | } 32 | 33 | public RouterDirectionsResponse(RoutingParameters params, Map dates, double distance, double time, LineString path, 34 | List partitions, List tlids, List restrictions, List directions, Collection notifications) { 35 | super(params, dates, distance, time, path, partitions, tlids, restrictions); 36 | this.directions = directions; 37 | this.notifications = notifications; 38 | for(Direction dir : directions) { 39 | if(dir instanceof AbstractTravelDirection) { 40 | ((AbstractTravelDirection)dir).setDistance(DistanceUnit.METRE.convertTo(((AbstractTravelDirection)dir).getDistance(), params.getDistanceUnit())); 41 | } 42 | if(dir.getLaneRequirements() != null) { 43 | for(LaneRequirement lr : dir.getLaneRequirements()) { 44 | lr.setDistance(DistanceUnit.METRE.convertTo(lr.getDistance(), params.getDistanceUnit())); 45 | } 46 | } 47 | } 48 | } 49 | 50 | public List getDirections() { 51 | return directions; 52 | } 53 | 54 | public Collection getNotifications() { 55 | return notifications; 56 | } 57 | 58 | @Override 59 | public void reproject(GeometryReprojector gr) { 60 | super.reproject(gr); 61 | for(Direction dir : directions) { 62 | dir.setPoint(gr.reproject(dir.getPoint(),getSrsCode())); 63 | if(dir.getLaneRequirements() != null) { 64 | for(LaneRequirement lr: dir.getLaneRequirements() ) { 65 | lr.setLocation(gr.reproject(lr.getLocation(), getSrsCode())); 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/RouterDistanceBetweenPairsResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.time.ZonedDateTime; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import org.locationtech.jts.geom.Point; 12 | 13 | import ca.bc.gov.ols.router.config.RouterConfig; 14 | import ca.bc.gov.ols.router.data.enums.DistanceUnit; 15 | import ca.bc.gov.ols.rowreader.DateType; 16 | 17 | public class RouterDistanceBetweenPairsResponse extends ApiResponse { 18 | 19 | protected List fromPoints; 20 | protected List toPoints; 21 | private int maxPairs; 22 | protected double[] distance; 23 | protected double[] time; 24 | protected String[] errors; 25 | private int curResult = 0; 26 | 27 | public RouterDistanceBetweenPairsResponse(RoutingParameters params, Map dates) { 28 | super(params, dates); 29 | fromPoints = params.getFromPoints(); 30 | toPoints = params.getToPoints(); 31 | maxPairs = params.getMaxPairs(); 32 | int numResults = fromPoints.size() * toPoints.size(); 33 | distance = new double[numResults]; 34 | time = new double[numResults]; 35 | errors = new String[numResults]; 36 | } 37 | 38 | public void addResult(double distance, double time) { 39 | if(distance < 0 || time < 0) { 40 | errors[curResult] = "No Route Found."; 41 | } else { 42 | errors[curResult] = null; 43 | } 44 | this.distance[curResult] = DistanceUnit.METRE.convertTo(distance, distanceUnit); 45 | this.time[curResult] = time; 46 | curResult++; 47 | } 48 | 49 | public void addResult(String error) { 50 | errors[curResult] = error; 51 | distance[curResult] = RouterConfig.ERROR_DISTANCE; 52 | time[curResult] = RouterConfig.ERROR_TIME; 53 | curResult++; 54 | } 55 | 56 | public List getFromPoints() { 57 | return fromPoints; 58 | } 59 | 60 | public void setFromPoints(List fromPoints) { 61 | this.fromPoints = fromPoints; 62 | } 63 | 64 | public List getToPoints() { 65 | return toPoints; 66 | } 67 | 68 | public void setToPoints(List toPoints) { 69 | this.toPoints = toPoints; 70 | } 71 | 72 | public int getMaxPairs() { 73 | return maxPairs; 74 | } 75 | 76 | public void setMaxPairs(int maxPairs) { 77 | this.maxPairs = maxPairs; 78 | } 79 | 80 | public String getDistanceStr(int result) { 81 | return distanceUnit.formatForDisplay(distance[result]); 82 | } 83 | 84 | public double getTime(int result) { 85 | return time[result]; 86 | } 87 | 88 | public String getError(int result) { 89 | return errors[result]; 90 | } 91 | 92 | @Override 93 | public void reproject(GeometryReprojector gr) { 94 | super.reproject(gr); 95 | fromPoints = reprojectPoints(fromPoints, gr); 96 | toPoints = reprojectPoints(toPoints, gr); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/RouterDistanceResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.time.ZonedDateTime; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import org.locationtech.jts.geom.Point; 12 | 13 | import ca.bc.gov.ols.router.data.enums.DistanceUnit; 14 | import ca.bc.gov.ols.rowreader.DateType; 15 | 16 | public class RouterDistanceResponse extends ApiResponse { 17 | 18 | protected List points; 19 | protected double distance; 20 | protected double time; 21 | 22 | public RouterDistanceResponse(RoutingParameters params, Map dates) { 23 | super(params, dates); 24 | points = params.getPoints(); 25 | distance = -1; 26 | time = -1; 27 | } 28 | 29 | public RouterDistanceResponse(RoutingParameters params, Map dates, double distance, double time) { 30 | super(params, dates); 31 | points = params.getPoints(); 32 | this.distance = DistanceUnit.METRE.convertTo(distance, params.getDistanceUnit()); 33 | this.time = time; 34 | } 35 | 36 | public List getPoints() { 37 | return points; 38 | } 39 | 40 | public String getDistanceStr() { 41 | return distanceUnit.formatForDisplay(distance); 42 | } 43 | 44 | public double getTime() { 45 | return time; 46 | } 47 | 48 | public boolean isRouteFound() { 49 | return distance >= 0; 50 | } 51 | 52 | @Override 53 | public void reproject(GeometryReprojector gr) { 54 | super.reproject(gr); 55 | points = reprojectPoints(points, gr); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/RouterOptimalDirectionsResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.time.ZonedDateTime; 8 | import java.util.Collection; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import org.locationtech.jts.geom.LineString; 13 | 14 | import ca.bc.gov.ols.router.directions.Direction; 15 | import ca.bc.gov.ols.router.directions.Partition; 16 | import ca.bc.gov.ols.router.notifications.Notification; 17 | import ca.bc.gov.ols.rowreader.DateType; 18 | 19 | 20 | public class RouterOptimalDirectionsResponse extends RouterDirectionsResponse implements RouterOptimizedResponse{ 21 | 22 | private long routingExecutionTime; 23 | private long optimizationExecutionTime; 24 | private int[] visitOrder; 25 | 26 | public RouterOptimalDirectionsResponse(RoutingParameters params, Map dates) { 27 | super(params, dates); 28 | visitOrder = new int[0]; 29 | } 30 | 31 | public RouterOptimalDirectionsResponse(RoutingParameters params, Map dates, double distance, double time, LineString path, 32 | List partitions, List tlids, List restrictions, List directions, Collection notifications, int[] visitOrder) { 33 | super(params, dates, distance, time, path, partitions, tlids, restrictions, directions, notifications); 34 | this.visitOrder = visitOrder; 35 | } 36 | 37 | public void setRoutingExecutionTime(long routingExecutionTime) { 38 | this.routingExecutionTime = routingExecutionTime; 39 | } 40 | 41 | public long getRoutingExecutionTime() { 42 | return routingExecutionTime; 43 | } 44 | 45 | public void setOptimizationExecutionTime(long optimizationExecutionTime) { 46 | this.optimizationExecutionTime = optimizationExecutionTime; 47 | } 48 | 49 | public long getOptimizationExecutionTime() { 50 | return optimizationExecutionTime; 51 | } 52 | 53 | public int[] getVisitOrder() { 54 | return visitOrder; 55 | } 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/RouterOptimalRouteResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.time.ZonedDateTime; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import org.locationtech.jts.geom.LineString; 12 | 13 | import ca.bc.gov.ols.router.directions.Partition; 14 | import ca.bc.gov.ols.rowreader.DateType; 15 | 16 | public class RouterOptimalRouteResponse extends RouterRouteResponse implements RouterOptimizedResponse { 17 | 18 | private long routingExecutionTime; 19 | private long optimizationExecutionTime; 20 | private int[] visitOrder; 21 | 22 | public RouterOptimalRouteResponse(RoutingParameters params, Map dates) { 23 | super(params, dates); 24 | } 25 | 26 | public RouterOptimalRouteResponse(RoutingParameters params, Map dates, double distance, double time, 27 | LineString path, List partitions, List tlids, List restrictions, int[] visitOrder) { 28 | super(params, dates, distance, time, path, partitions, tlids, restrictions); 29 | this.visitOrder = visitOrder; 30 | } 31 | 32 | public void setRoutingExecutionTime(long routingExecutionTime) { 33 | this.routingExecutionTime = routingExecutionTime; 34 | } 35 | 36 | public long getRoutingExecutionTime() { 37 | return routingExecutionTime; 38 | } 39 | 40 | public void setOptimizationExecutionTime(long optimizationExecutionTime) { 41 | this.optimizationExecutionTime = optimizationExecutionTime; 42 | } 43 | 44 | public long getOptimizationExecutionTime() { 45 | return optimizationExecutionTime; 46 | } 47 | 48 | public int[] getVisitOrder() { 49 | return visitOrder; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/RouterOptimizedResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | public interface RouterOptimizedResponse { 8 | public long getRoutingExecutionTime(); 9 | public long getOptimizationExecutionTime(); 10 | public int[] getVisitOrder(); 11 | } 12 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/RouterRouteResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import java.time.ZonedDateTime; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import org.locationtech.jts.geom.LineString; 12 | 13 | import ca.bc.gov.ols.router.directions.Partition; 14 | import ca.bc.gov.ols.rowreader.DateType; 15 | 16 | public class RouterRouteResponse extends RouterDistanceResponse { 17 | 18 | private LineString path; 19 | private List partitions; 20 | private List tlids; 21 | private List restrictions; 22 | 23 | public RouterRouteResponse(RoutingParameters params, Map dates) { 24 | super(params, dates); 25 | } 26 | 27 | public RouterRouteResponse(RoutingParameters params, Map dates, double distance, double time, LineString path, List partitions, List tlids, List restrictions) { 28 | super(params, dates, distance, time); 29 | this.path = path; 30 | this.partitions = partitions; 31 | this.tlids = tlids; 32 | this.restrictions = restrictions; 33 | } 34 | 35 | public LineString getPath() { 36 | return path; 37 | } 38 | 39 | public List getPartitions() { 40 | return partitions; 41 | } 42 | 43 | public List getTlids() { 44 | return tlids; 45 | } 46 | 47 | public List getRestrictions() { 48 | return restrictions; 49 | } 50 | 51 | @Override 52 | public void reproject(GeometryReprojector gr) { 53 | super.reproject(gr); 54 | path = gr.reproject(path, getSrsCode()); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/api/TurnRestrictionVis.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.api; 6 | 7 | import org.locationtech.jts.algorithm.Angle; 8 | import org.locationtech.jts.geom.LineString; 9 | import org.locationtech.jts.linearref.LengthIndexedLine; 10 | 11 | import ca.bc.gov.ols.router.data.WeeklyTimeRange; 12 | import ca.bc.gov.ols.router.data.enums.TurnDirection; 13 | import ca.bc.gov.ols.router.engine.basic.BasicGraphInternal; 14 | 15 | public class TurnRestrictionVis { 16 | private final WeeklyTimeRange restriction; 17 | private final TurnDirection direction; 18 | private final LineString fromFragment; 19 | private final LineString toFragment; 20 | private final int angle; 21 | 22 | public TurnRestrictionVis(BasicGraphInternal internalGraph, int[] ids, WeeklyTimeRange restriction) { 23 | this.restriction = restriction; 24 | LineString fromLine = internalGraph.getLineString(ids[0]); 25 | LengthIndexedLine fromLil = new LengthIndexedLine(fromLine); 26 | if(internalGraph.getReversed(ids[0])) { 27 | fromFragment = (LineString) fromLil.extractLine(10, 0); 28 | } else { 29 | double end = fromLil.getEndIndex(); 30 | fromFragment = (LineString) fromLil.extractLine(end-10, end); 31 | } 32 | LineString endFragment; 33 | LineString toLine = internalGraph.getLineString(ids[ids.length-1]); 34 | LengthIndexedLine toLil = new LengthIndexedLine(toLine); 35 | if(!internalGraph.getReversed(ids[ids.length-1])) { 36 | endFragment = (LineString) toLil.extractLine(0,10); 37 | } else { 38 | double end = toLil.getEndIndex(); 39 | endFragment = (LineString) toLil.extractLine(end, end-10); 40 | } 41 | 42 | if(ids.length == 3) { 43 | toFragment = endFragment; 44 | double angleBetween = Angle.angleBetweenOriented(fromFragment.getCoordinateN(fromFragment.getNumPoints()-2), 45 | toFragment.getCoordinateN(0), toFragment.getCoordinateN(1)); 46 | if(Math.abs(angleBetween) > Math.PI * 3 / 4) { 47 | direction = TurnDirection.CENTER; 48 | } else if(angleBetween < 0) { 49 | direction = TurnDirection.LEFT; 50 | } else { 51 | direction = TurnDirection.RIGHT; 52 | } 53 | } else { 54 | // TODO include all of the internal u-turn segments in the toFragment 55 | toFragment = endFragment; 56 | direction = TurnDirection.UTURN; 57 | } 58 | 59 | angle = (int) Math.round(Angle.toDegrees(Angle.normalizePositive(Angle.angle( 60 | fromFragment.getCoordinateN(fromFragment.getNumPoints()-2), 61 | fromFragment.getCoordinateN(fromFragment.getNumPoints()-1))))); 62 | } 63 | 64 | public WeeklyTimeRange getRestriction() { 65 | return restriction; 66 | } 67 | 68 | public TurnDirection getDirection() { 69 | return direction; 70 | } 71 | 72 | public LineString getFromFragment() { 73 | return fromFragment; 74 | } 75 | 76 | public LineString getToFragment() { 77 | return toFragment; 78 | } 79 | 80 | public int getAngle() { 81 | return angle; 82 | } 83 | 84 | public String toString() { 85 | return direction.name().charAt(0) + ": " + (restriction.isAlways() ? "ALWAYS" : restriction.getDaySet() + " " + restriction.getTimeRangeString()); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/config/InMemoryRouterConfigurationStore.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.config; 2 | 3 | import java.util.List; 4 | import java.util.Properties; 5 | import java.util.stream.Stream; 6 | 7 | import ca.bc.gov.ols.config.ConfigurationParameter; 8 | import ca.bc.gov.ols.config.ConfigurationStore; 9 | import ca.bc.gov.ols.config.FileConfigurationStore; 10 | 11 | public class InMemoryRouterConfigurationStore extends FileConfigurationStore { 12 | 13 | public InMemoryRouterConfigurationStore(Properties bootstrapConfig) { 14 | super(); 15 | } 16 | 17 | @Override 18 | public Stream getConfigParams() { 19 | ConfigurationParameter cp1 = new ConfigurationParameter("ROUTER", "dataSource.className", "ca.bc.gov.ols.router.datasource.TestDataSource"); 20 | ConfigurationParameter cp2 = new ConfigurationParameter("ROUTER", "baseSrsCode", "3005"); 21 | return Stream.of(cp1, cp2); 22 | } 23 | 24 | @Override 25 | public void setConfigParam(ConfigurationParameter param) { 26 | // not implemented 27 | } 28 | 29 | @Override 30 | public void removeConfigParam(ConfigurationParameter param) { 31 | // not implemented; 32 | } 33 | 34 | @Override 35 | public void replaceWith(ConfigurationStore configStore) { 36 | // not implemented 37 | } 38 | 39 | protected void writeConfigParams(List configParams) { 40 | // not implemented 41 | } 42 | 43 | @Override 44 | public void close() { 45 | // no-op 46 | } 47 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/config/RouterConfigurationStoreFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright © 2008-2019, Province of British Columbia 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package ca.bc.gov.ols.router.config; 17 | 18 | import java.lang.reflect.Constructor; 19 | import java.util.Properties; 20 | 21 | import org.slf4j.Logger; 22 | import org.slf4j.LoggerFactory; 23 | 24 | import ca.bc.gov.ols.config.ConfigurationStore; 25 | 26 | public class RouterConfigurationStoreFactory { 27 | private static final Logger logger = LoggerFactory.getLogger(RouterConfigurationStoreFactory.class); 28 | 29 | public static ConfigurationStore getConfigurationStore(Properties bootstrapConfig) { 30 | logger.info("RouterConfigurationStoreFactory.getConfigurationStore() called"); 31 | 32 | String configStoreClassName = bootstrapConfig.getProperty("OLS_ROUTER_CONFIGURATION_STORE"); 33 | logger.info("OLS_ROUTER_CONFIGURATION_STORE = " + configStoreClassName); 34 | try { 35 | Class cl = Class.forName(configStoreClassName); 36 | Constructor con = cl.getConstructor(new Class[] {Properties.class}); 37 | return (ConfigurationStore)con.newInstance(bootstrapConfig); 38 | } catch(ReflectiveOperationException roe) { 39 | throw new RuntimeException("Unable to load ConfigurationStore class: '" + configStoreClassName, roe); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/RoadClosureEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data; 6 | 7 | import java.time.LocalDateTime; 8 | import java.time.temporal.ChronoUnit; 9 | 10 | import ca.bc.gov.ols.router.time.TemporalSet; 11 | 12 | /** 13 | * A RoadClosureEvent is a type of RoadEvent where the road 14 | * is completely closed and cannot be traversed during the specified times. 15 | * 16 | * @author chodgson@refractions.net 17 | * 18 | */ 19 | public class RoadClosureEvent extends RoadEvent { 20 | 21 | public RoadClosureEvent(TemporalSet time) { 22 | super(time); 23 | } 24 | 25 | @Override 26 | public int getDelay(LocalDateTime dateTime) { 27 | LocalDateTime nextTime = time.after(dateTime); 28 | if(nextTime == null) { 29 | return -1; 30 | } 31 | return (int) dateTime.until(nextTime, ChronoUnit.SECONDS); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/RoadDelayEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | import ca.bc.gov.ols.router.time.TemporalSet; 10 | 11 | /** 12 | * A RoadDelayEvent is a type of RoadEvent that causes a known, 13 | * fixed delay in traversing the associated segment(s). 14 | * 15 | * @author chodgson@refractions.net 16 | */ 17 | public class RoadDelayEvent extends RoadEvent { 18 | private final int delay; // in seconds 19 | 20 | /** 21 | * Creates a RoadDelayEvent at the specified time, with the specified delay. 22 | * @param time a TemporalSet representing the set of times during which the specified delay should be applied 23 | * @param secondsDelay the number of seconds of delay which should be applied when traversing segments associate with this event 24 | */ 25 | public RoadDelayEvent(TemporalSet time, int secondsDelay) { 26 | super(time); 27 | this.delay = secondsDelay; 28 | } 29 | 30 | /** 31 | * Returns the delay, in seconds, caused by this road event 32 | * @return the delay, in seconds 33 | */ 34 | public int getDelay() { 35 | return delay; 36 | } 37 | 38 | @Override 39 | public int getDelay(LocalDateTime dateTime) { 40 | return delay; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/RoadEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | import ca.bc.gov.ols.router.time.TemporalSet; 10 | 11 | abstract public class RoadEvent { 12 | 13 | protected final TemporalSet time; 14 | 15 | public RoadEvent(TemporalSet time) { 16 | this.time = time; 17 | } 18 | 19 | public boolean contains(LocalDateTime dateTime) { 20 | return time.contains(dateTime); 21 | } 22 | 23 | public TemporalSet getTime() { 24 | return time; 25 | } 26 | 27 | abstract public int getDelay(LocalDateTime dateTime); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/RoadTruckNoticeEvent.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | import ca.bc.gov.ols.router.data.enums.TruckNoticeType; 10 | import ca.bc.gov.ols.router.time.TemporalSet; 11 | 12 | /** 13 | * A RoadTruckNoticeEvent is a type of RoadEvent where there is some 14 | * additional information that trucks need to be aware of when traveling on the road. 15 | * 16 | * @author chodgson@refractions.net 17 | * 18 | */ 19 | public class RoadTruckNoticeEvent extends RoadEvent { 20 | 21 | private TruckNoticeType type; 22 | private String notice; 23 | 24 | public RoadTruckNoticeEvent(TemporalSet time, TruckNoticeType type, String notice) { 25 | super(time); 26 | this.type = type; 27 | this.notice = notice; 28 | } 29 | 30 | public TruckNoticeType getType() { 31 | return type; 32 | } 33 | 34 | public String getNotice() { 35 | return notice; 36 | } 37 | 38 | @Override 39 | public int getDelay(LocalDateTime dateTime) { 40 | return 0; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/StreetIntersection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data; 6 | 7 | import org.locationtech.jts.geom.Point; 8 | 9 | public class StreetIntersection { 10 | 11 | private final int id; 12 | private final Point location; 13 | 14 | public StreetIntersection(int id, Point location) { 15 | this.id = id; 16 | this.location = location; 17 | } 18 | 19 | public int getId() { 20 | return id; 21 | } 22 | 23 | public Point getLocation() { 24 | return location; 25 | } 26 | 27 | @Override 28 | public boolean equals(Object obj) { 29 | return obj instanceof StreetIntersection && this.id == ((StreetIntersection)obj).id; 30 | } 31 | 32 | @Override 33 | public int hashCode() { 34 | return id; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/TurnClass.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.data; 2 | 3 | import ca.bc.gov.ols.router.data.enums.TurnDirection; 4 | 5 | public class TurnClass { 6 | 7 | private final int[] ids; 8 | private final TurnDirection turnDirection; 9 | 10 | public TurnClass(final int fromSegId, final int intId, final int toSegId, final TurnDirection turnDirection) { 11 | ids = new int[3]; 12 | ids[0] = fromSegId; 13 | ids[1] = intId; 14 | ids[2] = toSegId; 15 | this.turnDirection = turnDirection; 16 | } 17 | 18 | public TurnClass(String idSeq, TurnDirection turnDirection) { 19 | String[] stringIds = idSeq.split("\\|"); 20 | ids = new int[stringIds.length]; 21 | for(int i = 0; i < stringIds.length; i++) { 22 | ids[i] = Integer.parseInt(stringIds[i]); 23 | } 24 | this.turnDirection = turnDirection; 25 | } 26 | 27 | public String getIdSeqString() { 28 | StringBuilder sb = new StringBuilder(64); 29 | sb.append(ids[0] + "|" + ids[1] + "|" + ids[2]); 30 | for(int i = 3; i < ids.length; i++) { 31 | sb.append("|" + ids[i]); 32 | } 33 | return sb.toString(); 34 | } 35 | 36 | public int[] getIdSeq() { 37 | return ids; 38 | } 39 | 40 | public TurnDirection getTurnDirection() { 41 | return turnDirection; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/DayCode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.enums; 6 | 7 | import java.time.DayOfWeek; 8 | import java.util.EnumSet; 9 | import java.util.Set; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | public enum DayCode { 15 | MF(EnumSet.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, DayOfWeek.FRIDAY)), 16 | MS(EnumSet.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, DayOfWeek.FRIDAY, DayOfWeek.SATURDAY)), 17 | FS(EnumSet.of(DayOfWeek.FRIDAY, DayOfWeek.SATURDAY)), 18 | FU(EnumSet.of(DayOfWeek.FRIDAY, DayOfWeek.SATURDAY, DayOfWeek.SUNDAY)), 19 | SS(EnumSet.allOf(DayOfWeek.class)); 20 | 21 | private final static Logger logger = LoggerFactory.getLogger(DayCode.class.getCanonicalName()); 22 | 23 | private final EnumSet daySet; 24 | 25 | private DayCode(EnumSet daySet) { 26 | this.daySet = daySet; 27 | } 28 | 29 | public static Set parse(String dayCode) { 30 | if(dayCode != null && !dayCode.isEmpty()) { 31 | try { 32 | return DayCode.valueOf(dayCode.toUpperCase()).daySet; 33 | } catch (IllegalArgumentException iae) { 34 | logger.warn("Illegal DayCode \"{}\", ignored.", dayCode); 35 | } 36 | } 37 | return null; 38 | } 39 | 40 | public EnumSet getDaySet() { 41 | return daySet; 42 | } 43 | 44 | public static DayCode of(Set set) { 45 | for(DayCode dayCode : values()) { 46 | if(dayCode.daySet.equals(set)) { 47 | return dayCode; 48 | } 49 | } 50 | return null; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/End.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.enums; 6 | 7 | /** 8 | * The possible ends of a street. 9 | */ 10 | public enum End { 11 | FROM, TO; 12 | 13 | public static End convert(String s) { 14 | char c = s.charAt(0); 15 | switch(c) { 16 | case 'F': 17 | case 'f': 18 | return FROM; 19 | case 'T': 20 | case 't': 21 | return TO; 22 | default: 23 | throw new IllegalArgumentException("Invalid End) value: '" + c 24 | + "' (must be one of 'F', 'f', 'T', 't')"); 25 | } 26 | } 27 | 28 | public End opposite() { 29 | switch(this) { 30 | case FROM: 31 | return TO; 32 | case TO: 33 | return FROM; 34 | } 35 | return null; 36 | } 37 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/NavInfoType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.enums; 6 | 7 | public enum NavInfoType { 8 | IMP,DIR,TR,HR,ID,TRK,EV,TF,DE,SC; 9 | } 10 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/RestrictionSource.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.data.enums; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | public enum RestrictionSource { 7 | ITN, // Integrated Transport Network - the road network provided by GeoBC 8 | RDM; // Restriction Data Manager - restriction API provided by MOTI 9 | 10 | private static final Logger logger = LoggerFactory.getLogger(RestrictionSource.class.getCanonicalName()); 11 | 12 | /** 13 | * Takes a string value and returns the corresponding RestrictionSource object. 14 | * 15 | * @param restrictionSource string representation of the restrictionSource 16 | * @return the RestrictionSource corresponding to the given string representation. 17 | */ 18 | public static RestrictionSource convert(String restrictionSource) { 19 | for(RestrictionSource rs : values()) { 20 | if(rs.name().equalsIgnoreCase(restrictionSource)) { 21 | return rs; 22 | } 23 | } 24 | logger.warn("Invalid RestrictionSource value: '{}'.", restrictionSource); 25 | return null; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/RouteOption.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.enums; 6 | 7 | import java.util.EnumSet; 8 | import java.util.Set; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | public enum RouteOption { 14 | EVENTS("ev"), 15 | GLOBAL_DISTORTION_FIELD("gdf"), 16 | LOCAL_DISTORTION_FIELD("ldf"), 17 | SCHEDULING("sc"), 18 | TIME_DEPENDENCY("td"), 19 | TRANSPORT_LINE_ID("tl"), 20 | TRAFFIC("tf"), 21 | TURN_COSTS("tc"), 22 | TURN_RESTRICTIONS("tr"), 23 | XING_COSTS("xc"); 24 | 25 | private static final Logger logger = LoggerFactory.getLogger(RouteOption.class.getCanonicalName()); 26 | 27 | private String abbr; 28 | 29 | private RouteOption(String abbr) { 30 | this.abbr = abbr; 31 | } 32 | 33 | /** 34 | * Takes a string value and returns the corresponding RouteOption object. 35 | * 36 | * @param routeOption string representation of the RouteOption 37 | * @return the RouteOption corresponding to the given string representation. 38 | */ 39 | public static RouteOption convert(String routeOption) { 40 | if(routeOption != null && !routeOption.isEmpty()) { 41 | for(RouteOption ro : values()) { 42 | if(ro.abbr.equalsIgnoreCase(routeOption) || ro.name().equalsIgnoreCase(routeOption)) { 43 | return ro; 44 | } 45 | } 46 | } 47 | return null; 48 | } 49 | 50 | /** 51 | * Takes a string with a comma-separated list of RouteOption values 52 | * and returns an EnumSet of the corresponding RouteOptions. 53 | * 54 | * @param routeOptionList string of comma-separated list of RouteOption values 55 | * @return the EnumSet of RouteOptions corresponding to the given string list 56 | */ 57 | public static EnumSet fromList(String routeOptionList) { 58 | EnumSet optionSet = EnumSet.noneOf(RouteOption.class); 59 | String[] routeOptions = routeOptionList.split(","); 60 | for(String routeOption : routeOptions) { 61 | if(routeOption != null && !routeOption.isEmpty()) { 62 | for(RouteOption ro : values()) { 63 | if(ro.abbr.equalsIgnoreCase(routeOption) || ro.name().equalsIgnoreCase(routeOption)) { 64 | optionSet.add(ro); 65 | } 66 | } 67 | } 68 | } 69 | return optionSet; 70 | } 71 | 72 | @Override 73 | public String toString() { 74 | return abbr; 75 | } 76 | 77 | public static String setToString(Set enabledOptions) { 78 | StringBuilder sb = new StringBuilder(); 79 | for(RouteOption option : enabledOptions) { 80 | sb.append(option.abbr); 81 | sb.append(","); 82 | } 83 | if(sb.length() > 1) { 84 | sb.setLength(sb.length() - 1); 85 | } 86 | return sb.toString(); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/RoutingCriteria.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.enums; 6 | 7 | public enum RoutingCriteria { 8 | FASTEST("fastest"), 9 | SHORTEST("shortest"); 10 | 11 | private String label; 12 | 13 | private RoutingCriteria(String label) { 14 | this.label = label; 15 | } 16 | 17 | public static RoutingCriteria convert(String name) { 18 | for(RoutingCriteria rc : values()) { 19 | if(rc.label.equalsIgnoreCase(name)) { 20 | return rc; 21 | } 22 | } 23 | throw new IllegalArgumentException("Invalid RoutingCriteria value: '" 24 | + name + "'."); 25 | } 26 | 27 | public String toString() { 28 | return label; 29 | }} 30 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/TruckNoticeType.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.data.enums; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | public enum TruckNoticeType { 7 | RESTRICTION, 8 | ADVISORY, 9 | BORDER, 10 | FERRY; 11 | 12 | private static final Logger logger = LoggerFactory.getLogger(TruckNoticeType.class.getCanonicalName()); 13 | 14 | /** 15 | * Takes a string value and returns the corresponding TruckNoticeType object. 16 | * 17 | * @param truckNoticeType string representation of the TruckNoticeType 18 | * @return the TruckNoticeType corresponding to the given string representation. 19 | */ 20 | public static TruckNoticeType convert(String truckNoticeType) { 21 | if(truckNoticeType != null && !truckNoticeType.isEmpty()) { 22 | for(TruckNoticeType t : values()) { 23 | if(t.name().equalsIgnoreCase(truckNoticeType)) { 24 | return t; 25 | } 26 | } 27 | } 28 | logger.warn("Invalid TruckNoticeType value: '{}'.", truckNoticeType); 29 | return null; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/TurnDirection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.enums; 6 | 7 | public enum TurnDirection { 8 | LEFT, CENTER, RIGHT, UTURN; 9 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/TurnRestrictionType.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.data.enums; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | public enum TurnRestrictionType { 7 | I, // Implicit (generic) 8 | Y, // 2 or 3 ramp/turning lane intersection 9 | X, // 4 or more ramp/turning lane intersection 10 | V, // Divided merge U/V-turn 11 | U, // Divided U-turn 12 | E, // Explicit 13 | UNKNOWN; //Unknown 14 | 15 | private static final Logger logger = LoggerFactory.getLogger(TurnRestrictionType.class.getCanonicalName()); 16 | 17 | /** 18 | * Takes a string value and returns the corresponding TurnRestrictionType object. 19 | * 20 | * @param turnRestrictionType string representation of the turnRestrictionType 21 | * @return the TurnRestrictionType corresponding to the given string representation. 22 | */ 23 | public static TurnRestrictionType convert(String turnRestrictionType) { 24 | for(TurnRestrictionType t : values()) { 25 | if(t.name().equals(turnRestrictionType)) { 26 | return t; 27 | } 28 | } 29 | //logger.warn("Invalid TurnRestrictionType value: '{}'.", turnRestrictionType); 30 | return UNKNOWN; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/TurnTimeCode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.enums; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import ca.bc.gov.ols.router.data.WeeklyTimeRange; 11 | import static ca.bc.gov.ols.router.data.WeeklyTimeRange.*; 12 | 13 | public enum TurnTimeCode { 14 | MF_24(new WeeklyTimeRange(DayCode.MF.getDaySet(), TIME_RANGE_ALWAYS)), 15 | MF_AM(new WeeklyTimeRange(DayCode.MF.getDaySet(), TIME_RANGE_AM)), 16 | MF_AMPM(new WeeklyTimeRange(DayCode.MF.getDaySet(), TIME_RANGE_AMPM)), 17 | MF_DAY(new WeeklyTimeRange(DayCode.MF.getDaySet(), TIME_RANGE_DAY)), 18 | MF_PM(new WeeklyTimeRange(DayCode.MF.getDaySet(), TIME_RANGE_PM)), 19 | MS_24(new WeeklyTimeRange(DayCode.MS.getDaySet(), TIME_RANGE_ALWAYS)), 20 | MS_AM(new WeeklyTimeRange(DayCode.MS.getDaySet(), TIME_RANGE_AM)), 21 | MS_AMPM(new WeeklyTimeRange(DayCode.MS.getDaySet(), TIME_RANGE_AMPM)), 22 | MS_DAY(new WeeklyTimeRange(DayCode.MS.getDaySet(), TIME_RANGE_DAY)), 23 | MS_PM(new WeeklyTimeRange(DayCode.MS.getDaySet(), TIME_RANGE_PM)), 24 | SS_24(new WeeklyTimeRange(DayCode.SS.getDaySet(), TIME_RANGE_ALWAYS)), 25 | SS_AM(new WeeklyTimeRange(DayCode.SS.getDaySet(), TIME_RANGE_AM)), 26 | SS_AMPM(new WeeklyTimeRange(DayCode.SS.getDaySet(), TIME_RANGE_AMPM)), 27 | SS_DAY(new WeeklyTimeRange(DayCode.SS.getDaySet(), TIME_RANGE_DAY)), 28 | SS_PM(new WeeklyTimeRange(DayCode.SS.getDaySet(), TIME_RANGE_PM)); 29 | 30 | private final static Logger logger = LoggerFactory.getLogger(TurnTimeCode.class.getCanonicalName()); 31 | 32 | private final WeeklyTimeRange timeRange; 33 | 34 | private TurnTimeCode(WeeklyTimeRange timeRange) { 35 | this.timeRange = timeRange; 36 | } 37 | 38 | /** 39 | * Takes a string value and returns the corresponding TurnTimeCode object. 40 | * 41 | * @param turnTimeCode string representation of the DividerType 42 | * @return the TurnTimeCode corresponding to the given string representation. 43 | */ 44 | public static TurnTimeCode convert(String turnTimeCode) { 45 | if(turnTimeCode != null && !turnTimeCode.isEmpty()) { 46 | try { 47 | return TurnTimeCode.valueOf((turnTimeCode.substring(0, 2) + "_" + turnTimeCode.substring(3)).toUpperCase()); 48 | } catch (IllegalArgumentException iae) { 49 | logger.warn("Illegal turnTimeCode '{}' ignored.", turnTimeCode); 50 | } 51 | } 52 | return null; 53 | } 54 | 55 | public WeeklyTimeRange getTimeRange() { 56 | return timeRange; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/VehicleType.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.data.enums; 2 | 3 | import java.util.EnumSet; 4 | import java.util.Set; 5 | import java.util.function.Function; 6 | 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | public enum VehicleType { 11 | CAR, TRUCK; 12 | 13 | private final static Logger logger = LoggerFactory.getLogger(VehicleType.class); 14 | 15 | public static EnumSet fromList(String list) { 16 | if(list == null || list.isBlank()) return EnumSet.allOf(VehicleType.class); 17 | EnumSet set = EnumSet.noneOf(VehicleType.class); 18 | String[] items = list.split("\\|"); 19 | for(String item : items) { 20 | if(item != null && !item.isEmpty()) { 21 | try { 22 | set.add(VehicleType.valueOf(item.toUpperCase())); 23 | } catch(IllegalArgumentException iae) { 24 | logger.warn("Invalid VehicleType: '{}'", item); 25 | } 26 | } 27 | } 28 | return set; 29 | } 30 | 31 | public static String setToString(Set vehicleTypes) { 32 | if(vehicleTypes.equals(EnumSet.allOf(VehicleType.class))) { 33 | return ""; 34 | } 35 | StringBuilder sb = new StringBuilder(); 36 | for(VehicleType type : vehicleTypes) { 37 | sb.append(type); 38 | sb.append("|"); 39 | } 40 | sb.setLength(sb.length() - 1); 41 | return sb.toString(); 42 | } 43 | 44 | public static VehicleType convert(String s) { 45 | try { 46 | return valueOf(s.toUpperCase()); 47 | } catch(IllegalArgumentException iae) { 48 | return CAR; 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/enums/XingClass.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.data.enums; 2 | 3 | public enum XingClass { 4 | SMALLER, SAME, LARGER; 5 | 6 | public static XingClass convert(String s) { 7 | try { 8 | return valueOf(s); 9 | } catch(IllegalArgumentException iae) { 10 | return SAME; 11 | } 12 | } 13 | 14 | public double applyMultiplier(double xingCost, double mult) { 15 | switch(this) { 16 | case SMALLER: return xingCost * mult; 17 | case LARGER: return xingCost / mult; 18 | case SAME: 19 | default: return xingCost; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/vis/VisFeature.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.vis; 6 | 7 | import org.locationtech.jts.geom.Geometry; 8 | 9 | import ca.bc.gov.ols.router.data.enums.NavInfoType; 10 | 11 | public class VisFeature { 12 | private Geometry geom; 13 | private final NavInfoType type; 14 | private final String subType; 15 | private final String source; 16 | private final String detail; 17 | private final int angle; 18 | 19 | public VisFeature(Geometry geom, NavInfoType type) { 20 | this.geom = geom; 21 | this.type = type; 22 | this.subType = ""; 23 | this.source = ""; 24 | this.detail = ""; 25 | this.angle = 0; 26 | } 27 | 28 | public VisFeature(Geometry geom, NavInfoType type, String detail) { 29 | this.geom = geom; 30 | this.type = type; 31 | this.subType = null; 32 | this.source = ""; 33 | this.detail = detail; 34 | this.angle = 0; 35 | } 36 | 37 | public VisFeature(Geometry geom, NavInfoType type, String subType, String detail) { 38 | this.geom = geom; 39 | this.type = type; 40 | this.subType = subType; 41 | this.source = ""; 42 | this.detail = detail; 43 | this.angle = 0; 44 | } 45 | 46 | public VisFeature(Geometry geom, NavInfoType type, String subType, String source, String detail) { 47 | this.geom = geom; 48 | this.type = type; 49 | this.subType = subType; 50 | this.source = source; 51 | this.detail = detail; 52 | this.angle = 0; 53 | } 54 | 55 | public VisFeature(Geometry geom, NavInfoType type, String subType, String detail, int angle) { 56 | this.geom = geom; 57 | this.type = type; 58 | this.subType = subType; 59 | this.source = ""; 60 | this.detail = detail; 61 | this.angle = angle; 62 | } 63 | 64 | public Geometry getGeometry() { 65 | return geom; 66 | } 67 | 68 | public void setGeometry(Geometry geom) { 69 | this.geom = geom; 70 | } 71 | 72 | public NavInfoType getType() { 73 | return type; 74 | } 75 | 76 | public String getSubType() { 77 | return subType; 78 | } 79 | 80 | public String getSource() { 81 | return source; 82 | } 83 | 84 | public String getDetail() { 85 | return detail; 86 | } 87 | 88 | public int getAngle() { 89 | return angle; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/vis/VisLayer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.vis; 6 | 7 | import java.util.List; 8 | 9 | import org.locationtech.jts.geom.Envelope; 10 | import org.locationtech.jts.index.strtree.STRtree; 11 | 12 | public class VisLayer { 13 | 14 | private STRtree spatialIndex; 15 | 16 | public VisLayer() { 17 | spatialIndex = new STRtree(); 18 | } 19 | 20 | public void build() { 21 | spatialIndex.build(); 22 | } 23 | 24 | public void addMapGeom(VisFeature mapGeom) { 25 | spatialIndex.insert(mapGeom.getGeometry().getEnvelopeInternal(), mapGeom); 26 | } 27 | 28 | @SuppressWarnings("unchecked") 29 | public List within(Envelope env) { 30 | return spatialIndex.query(env); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/vis/VisLayers.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.vis; 6 | 7 | import java.util.EnumMap; 8 | import java.util.List; 9 | 10 | import org.locationtech.jts.geom.Envelope; 11 | 12 | import ca.bc.gov.ols.router.data.enums.NavInfoType; 13 | 14 | public class VisLayers { 15 | 16 | private EnumMap layers; 17 | 18 | public VisLayers() { 19 | layers = new EnumMap(NavInfoType.class); 20 | for(NavInfoType type : NavInfoType.values()) { 21 | layers.put(type, new VisLayer()); 22 | } 23 | } 24 | 25 | public void buildIndexes() { 26 | for(VisLayer layer : layers.values()) { 27 | layer.build(); 28 | } 29 | } 30 | 31 | 32 | public void addFeature(VisFeature mapGeom) { 33 | layers.get(mapGeom.getType()).addMapGeom(mapGeom); 34 | } 35 | 36 | public List featuresWithin(NavInfoType type, Envelope env) { 37 | return layers.get(type).within(env); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/data/vis/VisTurnRestriction.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.data.vis; 6 | 7 | import java.util.List; 8 | 9 | import org.locationtech.jts.geom.Geometry; 10 | import org.locationtech.jts.geom.LineString; 11 | 12 | import ca.bc.gov.ols.router.data.enums.NavInfoType; 13 | 14 | public class VisTurnRestriction extends VisFeature { 15 | 16 | private LineString fromFragment; 17 | private List toFragments; 18 | 19 | public VisTurnRestriction(Geometry geom, NavInfoType type, String subType, String detail, 20 | int angle, LineString fromFragment, List toFragments) { 21 | super(geom, type, subType, detail, angle); 22 | this.fromFragment = fromFragment; 23 | this.toFragments = toFragments; 24 | } 25 | 26 | public LineString getFromFragment() { 27 | return fromFragment; 28 | } 29 | 30 | public List getToFragments() { 31 | return toFragments; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/datasource/DataUpdateManager.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.datasource; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import org.locationtech.jts.geom.GeometryFactory; 9 | 10 | import ca.bc.gov.ols.router.config.RouterConfig; 11 | import ca.bc.gov.ols.router.restrictions.rdm.RdmFetcher; 12 | import ca.bc.gov.ols.router.restrictions.rdm.RdmParser; 13 | import ca.bc.gov.ols.router.restrictions.rdm.Restriction; 14 | 15 | public class DataUpdateManager { 16 | 17 | RdmParser rdmParser; 18 | RdmFetcher rdmFetcher; 19 | List restrictions = new ArrayList(); 20 | 21 | public DataUpdateManager(RouterConfig config) { 22 | rdmParser = new RdmParser(new GeometryFactory(RouterConfig.BASE_PRECISION_MODEL, 3005)); 23 | rdmFetcher = new RdmFetcher(config); 24 | } 25 | 26 | public List loadRdmRestrictions(Reader restrictionReader) throws IOException { 27 | return restrictions = rdmParser.parseRestrictions(restrictionReader); 28 | } 29 | 30 | public List fetchRdmRestrictions() throws IOException { 31 | return restrictions = rdmFetcher.fetchAll(rdmParser); 32 | } 33 | 34 | public List updateRdmRestrictions() throws IOException { 35 | List changes = rdmFetcher.fetchChanges(rdmParser); 36 | // TODO: probably also need the deletes 37 | // TODO: make all changes to the list 38 | 39 | return restrictions; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/datasource/RouterDataLoader.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.datasource; 6 | 7 | import java.io.IOException; 8 | 9 | import org.locationtech.jts.geom.GeometryFactory; 10 | import org.locationtech.jts.geom.PrecisionModel; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import ca.bc.gov.ols.router.config.RouterConfig; 15 | import ca.bc.gov.ols.router.data.StreetSegment; 16 | import ca.bc.gov.ols.router.data.TurnClass; 17 | import ca.bc.gov.ols.router.data.TurnRestriction; 18 | import ca.bc.gov.ols.router.data.enums.TurnDirection; 19 | import ca.bc.gov.ols.router.engine.GraphBuilder; 20 | import ca.bc.gov.ols.router.open511.parser.Open511Parser; 21 | import ca.bc.gov.ols.rowreader.RowReader; 22 | 23 | public class RouterDataLoader { 24 | private final static Logger logger = LoggerFactory.getLogger(RouterDataLoader.class.getCanonicalName()); 25 | 26 | private RouterConfig config; 27 | private RouterDataSource dataSource; 28 | private GraphBuilder graphBuilder; 29 | private DataUpdateManager dum; 30 | 31 | public RouterDataLoader(RouterConfig config, RouterDataSource dataSource, GraphBuilder graphBuilder, DataUpdateManager dum) { 32 | this.config = config; 33 | this.dataSource = dataSource; 34 | this.graphBuilder = graphBuilder; 35 | this.dum = dum; 36 | } 37 | 38 | public void loadData() throws IOException { 39 | logger.info("Starting loading Router data structure..."); 40 | long startTime = System.currentTimeMillis(); 41 | logger.debug("Max memory:{}", (Runtime.getRuntime().maxMemory() / 1000000)); 42 | 43 | StreetSegment seg; 44 | while((seg = dataSource.getNextSegment()) != null) { 45 | graphBuilder.addEdge(seg); 46 | } 47 | 48 | TurnRestriction cost; 49 | while((cost = dataSource.getNextTurnRestriction()) != null) { 50 | graphBuilder.addTurnRestriction(cost); 51 | } 52 | 53 | loadTurnClasses(dataSource.getTurnClassReader()); 54 | 55 | Open511Parser open511parser = new Open511Parser(new GeometryFactory(new PrecisionModel(),4326)); 56 | graphBuilder.addEvents(open511parser.parseEventResponse(dataSource.getOpen511Reader())); 57 | graphBuilder.addRestrictions(dum.loadRdmRestrictions(dataSource.getRestrictionReader())); 58 | 59 | graphBuilder.addTraffic(dataSource.getTrafficReader()); 60 | 61 | graphBuilder.addTruckNotices(dataSource.getTruckNoticeReader(), dataSource.getTruckNoticeMappingReader()); 62 | 63 | graphBuilder.addLocalDistortionField(dataSource.getLocalDistortionFieldReader()); 64 | 65 | graphBuilder.addSchedules(dataSource.getGtfs(), dataSource.getGTFSMappingReader()); 66 | 67 | graphBuilder.setDates(dataSource.getDates()); 68 | 69 | long elapsedTime = System.currentTimeMillis() - startTime; 70 | logger.info("Finished loading Router data structure ({} secs).", elapsedTime / 1000); 71 | logger.debug("Memory in use after loading(Megs): {}", 72 | ((Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1000000)); 73 | } 74 | 75 | private void loadTurnClasses(RowReader tcReader) { 76 | while(tcReader.next()) { 77 | String idSeq = tcReader.getString("EDGE_NODE_SET"); 78 | TurnDirection turnDirection = TurnDirection.valueOf(tcReader.getString("TURN_DIRECTION")); 79 | graphBuilder.addTurnClass(new TurnClass(idSeq, turnDirection)); 80 | } 81 | } 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/datasource/RouterDataSource.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.datasource; 6 | 7 | import java.io.IOException; 8 | import java.io.Reader; 9 | import java.time.ZonedDateTime; 10 | import java.util.Map; 11 | 12 | import org.onebusaway.gtfs.impl.GtfsDaoImpl; 13 | 14 | import ca.bc.gov.ols.router.data.StreetSegment; 15 | import ca.bc.gov.ols.router.data.TurnRestriction; 16 | import ca.bc.gov.ols.rowreader.DateType; 17 | import ca.bc.gov.ols.rowreader.RowReader; 18 | 19 | /** 20 | * The RouterDataSource provides access to the segment data. 21 | * 22 | * @author chodgson 23 | * 24 | */ 25 | public interface RouterDataSource { 26 | 27 | StreetSegment getNextSegment() throws IOException; 28 | 29 | String getNameBySegmentId(int segmentId); 30 | 31 | TurnRestriction getNextTurnRestriction() throws IOException; 32 | 33 | Reader getRestrictionReader() throws IOException; 34 | 35 | RowReader getTurnClassReader() throws IOException; 36 | 37 | Reader getOpen511Reader() throws IOException; 38 | 39 | RowReader getTrafficReader() throws IOException; 40 | 41 | GtfsDaoImpl getGtfs() throws IOException; 42 | 43 | RowReader getGTFSMappingReader() throws IOException; 44 | 45 | RowReader getTruckNoticeReader() throws IOException; 46 | 47 | RowReader getTruckNoticeMappingReader() throws IOException; 48 | 49 | RowReader getLocalDistortionFieldReader() throws IOException; 50 | 51 | Map getDates(); 52 | 53 | } 54 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/datasource/RouterDataSourceFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.datasource; 6 | 7 | import java.lang.reflect.Constructor; 8 | 9 | import org.locationtech.jts.geom.GeometryFactory; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import ca.bc.gov.ols.router.config.RouterConfig; 14 | 15 | public class RouterDataSourceFactory { 16 | private static final Logger logger = LoggerFactory.getLogger(RouterDataSourceFactory.class.getCanonicalName()); 17 | 18 | public static RouterDataSource getRouterDataSource(RouterConfig config,GeometryFactory geometryFactory) { 19 | logger.info("RouterDataSourceFactory.getRouterDataSource() called"); 20 | String dataSourceClassName = config.getDataSourceClassName(); 21 | // Super hack for now 22 | try { 23 | if(dataSourceClassName != null) { 24 | Class cl = Class.forName(dataSourceClassName); 25 | Constructor con = cl.getConstructor(new Class[] {RouterConfig.class, 26 | GeometryFactory.class}); 27 | return (RouterDataSource)con.newInstance(config, geometryFactory); 28 | } 29 | } catch(ReflectiveOperationException roe) { 30 | throw new RuntimeException("Unable to load specified dataSource.class: " 31 | + dataSourceClassName, roe); 32 | } 33 | throw new RuntimeException("No dataSource class specified in dataSource.class property"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/AbstractTravelDirection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | import org.locationtech.jts.geom.Point; 8 | 9 | public abstract class AbstractTravelDirection extends Direction { 10 | 11 | protected final String streetName; 12 | protected double distance = 0; 13 | protected double time = 0; 14 | 15 | public AbstractTravelDirection(Point point, String streetName) { 16 | super(point); 17 | this.streetName = streetName; 18 | } 19 | 20 | public AbstractTravelDirection(Point point, String streetName, double distance, double time) { 21 | super(point); 22 | this.streetName = streetName; 23 | this.distance = distance; 24 | this.time = time; 25 | } 26 | 27 | public String getStreetName() { 28 | return streetName; 29 | } 30 | 31 | public void setDistance(double distance) { 32 | this.distance = distance; 33 | } 34 | 35 | public void addDistance(double distance) { 36 | this.distance += distance; 37 | } 38 | 39 | public double getDistance() { 40 | return distance; 41 | } 42 | 43 | public void addTime(double time) { 44 | this.time += time; 45 | } 46 | 47 | public double getTime() { 48 | return time; 49 | } 50 | 51 | 52 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/CardinalDirection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | import org.locationtech.jts.algorithm.Angle; 8 | import org.locationtech.jts.geom.Coordinate; 9 | 10 | public enum CardinalDirection { 11 | NORTH, 12 | NORTHEAST, 13 | EAST, 14 | SOUTHEAST, 15 | SOUTH, 16 | SOUTHWEST, 17 | WEST, 18 | NORTHWEST; 19 | 20 | public static CardinalDirection getHeading(Coordinate c1, Coordinate c2) { 21 | double angle = Angle.angle(c1, c2); 22 | if(Math.abs(angle) > Math.PI * 7/8) { 23 | return WEST; 24 | } else if(angle < Math.PI * - 5/8) { 25 | return SOUTHWEST; 26 | } else if(angle < Math.PI * - 3/8) { 27 | return SOUTH; 28 | } else if(angle < Math.PI * - 1/8) { 29 | return SOUTHEAST; 30 | } else if(angle < Math.PI * 1/8) { 31 | return EAST; 32 | } else if(angle < Math.PI * 3/8) { 33 | return NORTHEAST; 34 | } else if(angle < Math.PI * 5/8) { 35 | return NORTH; 36 | } else { 37 | return NORTHWEST; 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/Direction.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashSet; 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | import org.locationtech.jts.geom.Point; 13 | 14 | import ca.bc.gov.ols.router.api.ApiResponse; 15 | import ca.bc.gov.ols.router.notifications.Notification; 16 | 17 | public abstract class Direction { 18 | protected Point point; 19 | protected Set notifications; 20 | protected List laneRequirements; 21 | 22 | public Direction(Point point) { 23 | this.point = point; 24 | } 25 | 26 | public Point getPoint() { 27 | return point; 28 | } 29 | 30 | public void setPoint(Point point) { 31 | this.point = point; 32 | } 33 | 34 | public Set getNotifications() { 35 | return notifications; 36 | } 37 | 38 | public List getLaneRequirements() { 39 | return laneRequirements; 40 | } 41 | 42 | public void addNotification(Notification notification) { 43 | if(notifications == null) { 44 | notifications = new HashSet(1); 45 | } 46 | notifications.add(notification); 47 | } 48 | 49 | // needs to account for null LaneRquirements in case of 50 | // restrictions off the end of partial segs at start/end of route 51 | public void addLaneRequirement(LaneRequirement lr) { 52 | if(lr == null) return; 53 | if(laneRequirements == null) { 54 | laneRequirements = new ArrayList(1); 55 | } 56 | laneRequirements.add(lr); 57 | } 58 | 59 | abstract public String getType(); 60 | 61 | abstract public String format(ApiResponse response); 62 | 63 | } 64 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/FerryDirection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | import org.locationtech.jts.geom.Point; 8 | 9 | import ca.bc.gov.ols.router.api.ApiResponse; 10 | import ca.bc.gov.ols.router.util.TimeHelper; 11 | 12 | public class FerryDirection extends AbstractTravelDirection { 13 | 14 | public FerryDirection(Point point, String streetName) { 15 | super(point, streetName); 16 | } 17 | 18 | @Override 19 | public String getType() { 20 | return "FERRY"; 21 | } 22 | 23 | @Override 24 | public String format(ApiResponse response) { 25 | String distStr = response.getDistanceUnit().formatForDirections(distance); 26 | return "Board " + streetName + " and travel " + distStr + " (" + TimeHelper.formatTime(time) + ")"; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/FinishDirection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | import org.locationtech.jts.geom.Point; 8 | 9 | import ca.bc.gov.ols.router.api.ApiResponse; 10 | 11 | public class FinishDirection extends Direction { 12 | 13 | public FinishDirection(Point point) { 14 | super(point); 15 | } 16 | 17 | @Override 18 | public String getType() { 19 | return "FINISH"; 20 | } 21 | 22 | @Override 23 | public String format(ApiResponse response) { 24 | return "Finish!"; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/Partition.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.directions; 2 | 3 | import java.util.EnumMap; 4 | import java.util.EnumSet; 5 | 6 | import ca.bc.gov.ols.router.engine.basic.Attribute; 7 | import ca.bc.gov.ols.router.engine.basic.QueryGraph; 8 | 9 | public class Partition { 10 | private int index; 11 | private EnumMap values; 12 | private double distance = 0; 13 | 14 | public Partition(int index, EnumSet attributes, QueryGraph graph, int edgeId) { 15 | this.index = index; 16 | values = new EnumMap(Attribute.class); 17 | for(Attribute attr : attributes) { 18 | values.put(attr, attr.get(graph, edgeId)); 19 | } 20 | } 21 | 22 | public int getIndex() { 23 | return index; 24 | } 25 | 26 | public EnumMap getValues() { 27 | return values; 28 | } 29 | 30 | public double getDistance() { 31 | return distance; 32 | } 33 | 34 | public void setDistance(double distance) { 35 | this.distance = distance; 36 | } 37 | 38 | public void addDistance(double distance) { 39 | this.distance += distance; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/StartDirection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | import org.locationtech.jts.geom.Point; 8 | 9 | import ca.bc.gov.ols.router.api.ApiResponse; 10 | import ca.bc.gov.ols.router.util.TimeHelper; 11 | 12 | public class StartDirection extends AbstractTravelDirection { 13 | private final CardinalDirection heading; 14 | 15 | public StartDirection(Point point, String streetName, CardinalDirection heading) { 16 | super(point, streetName); 17 | this.heading = heading; 18 | } 19 | 20 | @Override 21 | public String getType() { 22 | return "START"; 23 | } 24 | 25 | public CardinalDirection getHeading() { 26 | return heading; 27 | } 28 | 29 | @Override 30 | public String format(ApiResponse response) { 31 | String distStr = response.getDistanceUnit().formatForDirections(distance); 32 | String str = "Head " + heading.toString().toLowerCase() + " on " + streetName + (distStr.isEmpty() ? "" : (" for " + distStr)) 33 | + (time == 0 ? "" : (" (" + TimeHelper.formatTime(time) + ")")); 34 | return str; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/StopoverDirection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | import org.locationtech.jts.geom.Point; 8 | 9 | import ca.bc.gov.ols.router.api.ApiResponse; 10 | 11 | public class StopoverDirection extends Direction { 12 | private final int stopNum; 13 | 14 | public StopoverDirection(Point point, int stopNum) { 15 | super(point); 16 | this.stopNum = stopNum; 17 | } 18 | 19 | @Override 20 | public String getType() { 21 | return "STOPOVER"; 22 | } 23 | 24 | @Override 25 | public String format(ApiResponse response) { 26 | return "Stopover " + stopNum; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/StreetDirection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | import org.locationtech.jts.geom.Point; 8 | 9 | import ca.bc.gov.ols.router.api.ApiResponse; 10 | import ca.bc.gov.ols.router.util.TimeHelper; 11 | 12 | public class StreetDirection extends AbstractTravelDirection { 13 | protected final StreetDirectionType type; 14 | 15 | public StreetDirection(Point point, StreetDirectionType type, String streetName) { 16 | super(point, streetName); 17 | this.type = type; 18 | } 19 | 20 | public StreetDirection(Point point, StreetDirectionType type, String streetName, double distance, double time) { 21 | super(point, streetName, distance, time); 22 | this.type = type; 23 | } 24 | 25 | @Override 26 | public String getType() { 27 | return type.name(); 28 | } 29 | 30 | public String format(ApiResponse response) { 31 | String distStr = response.getDistanceUnit().formatForDirections(distance); 32 | String str = type.toString() + " onto " + streetName + (distStr.isEmpty() ? "" : (" for " + distStr)) 33 | + (time == 0 ? "" : (" (" + TimeHelper.formatTime(time) + ")")); 34 | return str; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/directions/StreetDirectionType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.directions; 6 | 7 | public enum StreetDirectionType { 8 | TURN_SLIGHT_LEFT("Turn slight left"), 9 | TURN_LEFT("Turn left"), 10 | TURN_SHARP_LEFT("Turn sharp left"), 11 | TURN_SLIGHT_RIGHT("Turn slight right"), 12 | TURN_RIGHT("Turn right"), 13 | TURN_SHARP_RIGHT("Turn sharp right"), 14 | CONTINUE("Continue"); 15 | 16 | private String wording; 17 | 18 | private StreetDirectionType(String wording) { 19 | this.wording = wording; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return wording; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/GraphBuilder.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine; 6 | 7 | import java.io.IOException; 8 | import java.time.ZonedDateTime; 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | import org.onebusaway.gtfs.impl.GtfsDaoImpl; 13 | 14 | import ca.bc.gov.ols.router.data.StreetSegment; 15 | import ca.bc.gov.ols.router.data.TurnClass; 16 | import ca.bc.gov.ols.router.data.TurnRestriction; 17 | import ca.bc.gov.ols.router.open511.EventResponse; 18 | import ca.bc.gov.ols.router.restrictions.rdm.Restriction; 19 | import ca.bc.gov.ols.rowreader.DateType; 20 | import ca.bc.gov.ols.rowreader.RowReader; 21 | 22 | public interface GraphBuilder { 23 | 24 | public abstract void addEdge(StreetSegment seg); 25 | 26 | public default void addTurnRestriction(TurnRestriction cost) {} 27 | 28 | public default void addTurnClass(TurnClass turnClass) {} 29 | 30 | public default void addRestrictions(List parseRestrictions) {} 31 | 32 | public default void addEvents(EventResponse eventResponse) {} 33 | 34 | public default void addTraffic(RowReader trafficReader) {} 35 | 36 | public default void addSchedules(GtfsDaoImpl gtfs, RowReader mappingReader) throws IOException {} 37 | 38 | public default void addTruckNotices(RowReader truckNoticeReader, RowReader truckNoticeMappingReader) {} 39 | 40 | public default void addLocalDistortionField(RowReader localDistortionFieldReader) {} 41 | 42 | public abstract void setDates(Map dates); 43 | 44 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/Attribute.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.engine.basic; 2 | 3 | import java.util.EnumSet; 4 | import java.util.function.BiFunction; 5 | 6 | public enum Attribute { 7 | isFerry((g,i) -> g.getFerryInfo(i) != null), 8 | isTruckRoute((g,i) -> g.isTruckRoute(i)), 9 | locality((g,i) -> g.getLocality(i)), 10 | ownership((g,i) -> g.getOwnership(i)); 11 | 12 | private BiFunction method; 13 | 14 | private Attribute(BiFunction method) { 15 | this.method = method; 16 | } 17 | 18 | public Object get(QueryGraph graph, Integer edgeId) { 19 | return method.apply(graph, edgeId); 20 | } 21 | 22 | /** 23 | * Takes a string with a comma-separated list of Attribute values 24 | * and returns an EnumSet of the corresponding Attributes. 25 | * 26 | * @param attributeList string of comma-separated list of Attribute values 27 | * @return the EnumSet of Attributes corresponding to the given string list 28 | */ 29 | public static EnumSet fromList(String attributeList) { 30 | EnumSet attrSet = EnumSet.noneOf(Attribute.class); 31 | String[] attrs = attributeList.split(","); 32 | for(String attr : attrs) { 33 | if(attr != null && !attr.isEmpty()) { 34 | for(Attribute a : values()) { 35 | if(a.name().equalsIgnoreCase(attr)) { 36 | attrSet.add(a); 37 | } 38 | } 39 | } 40 | } 41 | return attrSet; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/CostFunction.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine.basic; 6 | 7 | @FunctionalInterface 8 | public interface CostFunction { 9 | 10 | R apply(A a, B b, C c); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/DijkstraWalker.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine.basic; 6 | 7 | import java.util.ArrayList; 8 | import java.util.HashSet; 9 | import java.util.List; 10 | 11 | /* 12 | * Represents one step in a graph traversal. 13 | */ 14 | public record DijkstraWalker( 15 | Edge edge, // the edge just traversed 16 | double cost, // the cumulative cost from start to the nodeId 17 | double time, // the cumulative time from start to the nodeId 18 | double dist, // the cumulative distance from start to the nodeId 19 | int waitTime, // the cumulative waitTime from start to the nodeId 20 | DijkstraWalker from // a reference to the previous step 21 | ) implements Comparable { 22 | 23 | @Override 24 | public int compareTo(DijkstraWalker other) { 25 | return Double.compare(cost, other.cost); 26 | } 27 | 28 | public List getEdgeChain() { 29 | ArrayList chain = new ArrayList(); 30 | buildEdgeChain(chain); 31 | return chain; 32 | } 33 | 34 | private void buildEdgeChain(List chain) { 35 | chain.add(edge.id); 36 | if(from != null) { 37 | from.buildEdgeChain(chain); 38 | } 39 | } 40 | 41 | public List checkForDuplicateEdges() { 42 | List dups = new ArrayList(); 43 | List chain = getEdgeChain(); 44 | HashSet set = new HashSet(chain.size()); 45 | for(Integer edgeId : chain) { 46 | if(!set.add(edgeId)) { 47 | dups.add(edgeId); 48 | } 49 | } 50 | return dups; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/EdgeList.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine.basic; 6 | 7 | import gnu.trove.list.array.TDoubleArrayList; 8 | import gnu.trove.list.array.TIntArrayList; 9 | 10 | public class EdgeList { 11 | private static final int DEFAULT_INITIAL_CAPACITY = 16; 12 | private TIntArrayList edges; 13 | //private BitSet forward; 14 | private TDoubleArrayList times; 15 | private TDoubleArrayList dists; 16 | private TIntArrayList waitTimes; 17 | private WayPoint startWp; 18 | private WayPoint endWp; 19 | 20 | public EdgeList() { 21 | this(DEFAULT_INITIAL_CAPACITY); 22 | } 23 | 24 | public EdgeList(int initialCapacity) { 25 | edges = new TIntArrayList(initialCapacity); 26 | //forward = new BitSet(initialCapacity); 27 | times = new TDoubleArrayList(initialCapacity); 28 | dists = new TDoubleArrayList(initialCapacity); 29 | waitTimes = new TIntArrayList(initialCapacity); 30 | } 31 | 32 | public void add(int edgeId, double time, double dist, int waitTime) { 33 | edges.add(edgeId); 34 | //forward.set(edges.size()-1, isForward); 35 | times.add(time); 36 | dists.add(dist); 37 | waitTimes.add(waitTime); 38 | } 39 | 40 | public int edgeId(int index) { 41 | return edges.get(index); 42 | } 43 | 44 | // public boolean forward(int index) { 45 | // return forward.get(index); 46 | // } 47 | 48 | public double time(int index) { 49 | return times.get(index); 50 | } 51 | 52 | public double dist(int index) { 53 | return dists.get(index); 54 | } 55 | 56 | public int waitTime(int index) { 57 | return waitTimes.get(index); 58 | } 59 | 60 | public WayPoint getStartEdge() { 61 | return startWp; 62 | } 63 | 64 | public WayPoint getEndEdge() { 65 | return endWp; 66 | } 67 | 68 | public void setStartWayPoint(WayPoint startWp) { 69 | this.startWp = startWp; 70 | } 71 | 72 | public void setEndWayPoint(WayPoint endWp) { 73 | this.endWp = endWp; 74 | } 75 | 76 | 77 | public int size() { 78 | return edges.size(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/EventLookup.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine.basic; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.List; 11 | import java.util.stream.Collectors; 12 | 13 | import ca.bc.gov.ols.router.data.RoadEvent; 14 | import gnu.trove.map.hash.TIntObjectHashMap; 15 | 16 | public class EventLookup { 17 | 18 | private TIntObjectHashMap> eventMap; 19 | 20 | public EventLookup() { 21 | eventMap = new TIntObjectHashMap>(); 22 | } 23 | 24 | public void addEvent(int edgeId, RoadEvent evt) { 25 | if(edgeId == BasicGraphInternal.NO_EDGE) return; 26 | ArrayList eventList = eventMap.get(edgeId); 27 | if(eventList == null) { 28 | eventList = new ArrayList(1); 29 | eventMap.put(edgeId, eventList); 30 | } 31 | eventList.add(evt); 32 | } 33 | 34 | public void addEvent(List edgeIds, RoadEvent evt) { 35 | for(int edgeId : edgeIds) { 36 | addEvent(edgeId, evt); 37 | } 38 | } 39 | 40 | public List lookup(final int edgeId, final LocalDateTime dateTime) { 41 | ArrayList eventList = eventMap.get(edgeId); 42 | if(eventList == null) { 43 | return Collections.emptyList(); 44 | } 45 | return eventList.stream().filter(r -> r.contains(dateTime)).collect(Collectors.toList()); 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/FerryInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine.basic; 6 | 7 | public class FerryInfo { 8 | 9 | private final int minWaitTime; 10 | private final int travelTime; 11 | private boolean isScheduled; 12 | 13 | public FerryInfo(int minWaitTime, int travelTime, boolean isScheduled) { 14 | this.minWaitTime = minWaitTime; 15 | this.travelTime = travelTime; 16 | this.isScheduled = isScheduled; 17 | } 18 | 19 | public int getMinWaitTime() { 20 | return minWaitTime; 21 | } 22 | 23 | public int getTravelTime() { 24 | return travelTime; 25 | } 26 | 27 | public boolean isScheduled() { 28 | return isScheduled; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/GlobalDistortionField.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.engine.basic; 2 | 3 | import java.io.IOException; 4 | import java.util.Collections; 5 | import java.util.EnumMap; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.Map.Entry; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import com.google.gson.stream.JsonWriter; 14 | 15 | import ca.bc.gov.ols.enums.RoadClass; 16 | import ca.bc.gov.ols.router.data.enums.VehicleType; 17 | 18 | public class GlobalDistortionField { 19 | private static final Logger logger = LoggerFactory.getLogger(GlobalDistortionField.class.getCanonicalName()); 20 | 21 | private EnumMap truckRouteField; 22 | private EnumMap baseField; 23 | 24 | public GlobalDistortionField() { 25 | init(); 26 | } 27 | 28 | public GlobalDistortionField(GlobalDistortionField source) { 29 | this.truckRouteField = source.truckRouteField.clone(); 30 | this.baseField = source.baseField.clone(); 31 | } 32 | 33 | public GlobalDistortionField(String gdfString) { 34 | init(); 35 | applyString(gdfString); 36 | } 37 | 38 | private void init() { 39 | truckRouteField = new EnumMap(RoadClass.class); 40 | baseField = new EnumMap(RoadClass.class); 41 | for(RoadClass rc : RoadClass.values()) { 42 | truckRouteField.put(rc, 1.0); 43 | baseField.put(rc, 1.0); 44 | } 45 | } 46 | 47 | public void applyString(String gdfString) { 48 | if(gdfString == null || gdfString.isEmpty()) return; 49 | String[] entries = gdfString.split("\\,"); 50 | for(String entry : entries) { 51 | try { 52 | String[] pair = entry.split("\\:"); 53 | EnumMap map = baseField; 54 | if(pair[0].endsWith(".truck")) { 55 | map = truckRouteField; 56 | pair[0] = pair[0].substring(0,pair[0].lastIndexOf('.')); 57 | } 58 | RoadClass rc = RoadClass.convert(pair[0]); 59 | if(RoadClass.UNKNOWN == rc) { 60 | throw new Exception("Unknown RoadClass: " + pair[0]); 61 | } 62 | map.put(rc, Double.parseDouble(pair[1])); 63 | } catch(Exception e) { 64 | logger.warn("Invalid Global Distortion entry ignored: {}", entry); 65 | } 66 | } 67 | } 68 | 69 | public double lookup(RoadClass roadClass, boolean isTruckRoute) { 70 | Double ff; 71 | if(isTruckRoute) { 72 | ff = truckRouteField.get(roadClass); 73 | } else { 74 | ff = baseField.get(roadClass); 75 | } 76 | if(ff == null) { 77 | return 1; 78 | } 79 | return ff; 80 | } 81 | 82 | public Map getTruckField() { 83 | return Collections.unmodifiableMap(truckRouteField); 84 | } 85 | 86 | public Map getNonTruckField() { 87 | return Collections.unmodifiableMap(baseField); 88 | } 89 | 90 | public Map toMap(VehicleType type) { 91 | HashMap map = new HashMap(); 92 | for(Entry entry : baseField.entrySet()) { 93 | if(entry.getKey().isRouteable()) { 94 | map.put(entry.getKey().toString(), entry.getValue()); 95 | } 96 | } 97 | if(VehicleType.TRUCK == type) { 98 | for(Entry entry : truckRouteField.entrySet()) { 99 | if(entry.getKey().isRouteable()) { 100 | map.put(entry.getKey().toString() + ".truck", entry.getValue()); 101 | } 102 | } 103 | } 104 | return map; 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/SegmentIdLookup.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.engine.basic; 2 | 3 | public interface SegmentIdLookup { 4 | 5 | int[] getEdgesForSegment(int segmentId); 6 | 7 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/SplitEdge.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.engine.basic; 2 | 3 | import org.locationtech.jts.geom.LineString; 4 | 5 | import ca.bc.gov.ols.router.data.enums.RestrictionSource; 6 | import ca.bc.gov.ols.router.restrictions.Constraint; 7 | import ca.bc.gov.ols.util.MapList; 8 | 9 | class SplitEdge extends Edge { 10 | Edge baseEdge; 11 | LineString lineString; 12 | MapList restrictions; 13 | 14 | public SplitEdge(int edgeId, Edge baseEdge, int otherEdgeId, int fromNodeId, int toNodeId, 15 | LineString lineString, MapList restrictions) { 16 | super(edgeId, fromNodeId, toNodeId, baseEdge.data, baseEdge.reversed); 17 | this.baseEdge = baseEdge; 18 | this.otherEdgeId = otherEdgeId; 19 | this.lineString = lineString; 20 | this.restrictions = restrictions; 21 | } 22 | 23 | // TODO Maybe move all the property accessors from the graph/querygraph to the edge/splitedge 24 | // might be faster than using the graph 25 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/TrafficLookup.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine.basic; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | import gnu.trove.map.hash.TIntObjectHashMap; 10 | 11 | public class TrafficLookup { 12 | TIntObjectHashMap traffic; 13 | 14 | TrafficLookup(TIntObjectHashMap traffic) { 15 | this.traffic = traffic; 16 | } 17 | 18 | public short lookup(int edgeId, LocalDateTime time) { 19 | short[] t = traffic.get(edgeId); 20 | if(t == null) return 0; 21 | int dayOffset = time.getDayOfWeek().getValue() - 1; 22 | int offset = dayOffset * 24 + time.getHour(); 23 | short a = t[offset]; 24 | short b = t[(offset+1) % (7*24)]; 25 | // scale linearly between hours based on the minute 26 | double scale = (double)time.getMinute() / 60.0; 27 | return (short)Math.round(a * (1 - scale) + b * scale); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/basic/WayPoint.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine.basic; 6 | 7 | import java.util.List; 8 | 9 | import org.locationtech.jts.geom.Point; 10 | 11 | public record WayPoint ( 12 | List outgoingEdgeIds, 13 | List incomingEdgeIds, 14 | Point point 15 | ) {} 16 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/engine/graphhopper/GraphHopperCoordinateSequence.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.engine.graphhopper; 6 | 7 | import com.graphhopper.util.PointList; 8 | import org.locationtech.jts.geom.Coordinate; 9 | import org.locationtech.jts.geom.CoordinateSequence; 10 | import org.locationtech.jts.geom.Envelope; 11 | 12 | public class GraphHopperCoordinateSequence implements CoordinateSequence { 13 | 14 | private PointList points; 15 | 16 | public GraphHopperCoordinateSequence(PointList points) { 17 | this.points = points; 18 | } 19 | 20 | public GraphHopperCoordinateSequence clone() { 21 | return new GraphHopperCoordinateSequence(points.clone(false)); 22 | } 23 | 24 | @Override 25 | public CoordinateSequence copy() { 26 | return new GraphHopperCoordinateSequence(points.clone(false)); 27 | } 28 | 29 | 30 | 31 | @Override 32 | public int getDimension() { 33 | return 2; 34 | } 35 | 36 | @Override 37 | public Coordinate getCoordinate(int i) { 38 | return new Coordinate(points.getLon(i), points.getLat(i)); 39 | } 40 | 41 | @Override 42 | public Coordinate getCoordinateCopy(int i) { 43 | return new Coordinate(points.getLon(i), points.getLat(i)); 44 | } 45 | 46 | @Override 47 | public void getCoordinate(int index, Coordinate coord) { 48 | coord.x = points.getLon(index); 49 | coord.y = points.getLat(index); 50 | } 51 | 52 | @Override 53 | public double getX(int index) { 54 | return points.getLon(index); 55 | } 56 | 57 | @Override 58 | public double getY(int index) { 59 | return points.getLat(index); 60 | } 61 | 62 | @Override 63 | public double getOrdinate(int index, int ordinateIndex) { 64 | switch(ordinateIndex) { 65 | case 0: return points.getLon(index); 66 | case 1: return points.getLat(index); 67 | default: return 0; 68 | } 69 | } 70 | 71 | @Override 72 | public int size() { 73 | return points.getSize(); 74 | } 75 | 76 | @Override 77 | public void setOrdinate(int index, int ordinateIndex, double value) { 78 | switch(ordinateIndex) { 79 | case 0: points.set(index, points.getLat(index), value, 0); 80 | break; 81 | case 1: points.set(index, value, points.getLon(index), 0); 82 | break; 83 | default: 84 | } 85 | } 86 | 87 | @Override 88 | public Coordinate[] toCoordinateArray() { 89 | Coordinate[] coords = new Coordinate[points.size()]; 90 | for(int i = 0; i < points.size(); i++) { 91 | coords[i] = getCoordinate(i); 92 | } 93 | return coords; 94 | } 95 | 96 | @Override 97 | public Envelope expandEnvelope(Envelope env) { 98 | for(int i = 0; i < points.size(); i++) { 99 | env.expandToInclude(points.getLon(i), points.getLat(i)); 100 | } 101 | return env; 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/notifications/EventWaitNotification.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.notifications; 6 | 7 | import ca.bc.gov.ols.router.util.TimeHelper; 8 | 9 | 10 | public class EventWaitNotification implements Notification { 11 | private int time = 0; 12 | 13 | public EventWaitNotification(int time) { 14 | this.time = time; 15 | } 16 | 17 | @Override 18 | public String getType() { 19 | return "EventWait"; 20 | } 21 | 22 | @Override 23 | public String getMessage() { 24 | return "Wait for " + TimeHelper.formatTime(time) + " due to delays"; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/notifications/FerryWaitNotification.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.notifications; 6 | 7 | import ca.bc.gov.ols.router.util.TimeHelper; 8 | 9 | public class FerryWaitNotification implements Notification { 10 | private final String streetName; 11 | private int time = 0; 12 | 13 | public FerryWaitNotification(String streetName, int time) { 14 | this.streetName = streetName; 15 | this.time = time; 16 | } 17 | 18 | @Override 19 | public String getType() { 20 | return "FerryWait"; 21 | } 22 | 23 | @Override 24 | public String getMessage() { 25 | return "Wait for " + streetName + " for " + TimeHelper.formatTime(time); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/notifications/Notification.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.notifications; 6 | 7 | public interface Notification { 8 | 9 | public String getType(); 10 | public String getMessage(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/notifications/OversizeNotification.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.notifications; 6 | 7 | 8 | public class OversizeNotification implements Notification { 9 | 10 | @Override 11 | public String getType() { 12 | return "Oversize"; 13 | } 14 | 15 | @Override 16 | public String getMessage() { 17 | return "The vehicle dimensions specified are larger than standard and would require an oversize permit."; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/notifications/TruckNotification.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.notifications; 6 | 7 | import java.util.Objects; 8 | 9 | import ca.bc.gov.ols.router.data.RoadTruckNoticeEvent; 10 | import ca.bc.gov.ols.router.data.enums.TruckNoticeType; 11 | import ca.bc.gov.ols.util.StringUtils; 12 | 13 | 14 | public class TruckNotification implements Notification { 15 | private TruckNoticeType type = null; 16 | private String message; 17 | 18 | public TruckNotification(RoadTruckNoticeEvent evt) { 19 | type = evt.getType(); 20 | message = evt.getNotice(); 21 | } 22 | 23 | @Override 24 | public String getType() { 25 | return "Truck" + StringUtils.capitalizeFirst(type.toString()); 26 | } 27 | 28 | @Override 29 | public String getMessage() { 30 | return message; 31 | } 32 | 33 | @Override 34 | public boolean equals(Object o) { 35 | if(o instanceof TruckNotification 36 | && type.equals(((TruckNotification)o).type) 37 | && message.equals(((TruckNotification)o).message)) { 38 | return true; 39 | } 40 | return false; 41 | } 42 | 43 | @Override 44 | public int hashCode() { 45 | return Objects.hash(type, message); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/Area.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | public class Area { 8 | private String name; 9 | private String id; 10 | private String url; 11 | 12 | public String getName() { 13 | return name; 14 | } 15 | 16 | public void setName(String name) { 17 | this.name = name; 18 | } 19 | 20 | public String getId() { 21 | return id; 22 | } 23 | 24 | public void setId(String id) { 25 | this.id = id; 26 | } 27 | 28 | public String getUrl() { 29 | return url; 30 | } 31 | 32 | public void setUrl(String url) { 33 | this.url = url; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/EventResponse.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | import java.util.List; 8 | 9 | public class EventResponse { 10 | List events; 11 | Pagination pagination; 12 | Meta meta; 13 | 14 | public List getEvents() { 15 | return events; 16 | } 17 | public void setEvents(List events) { 18 | this.events = events; 19 | } 20 | public Pagination getPagination() { 21 | return pagination; 22 | } 23 | public void setPagination(Pagination pagination) { 24 | this.pagination = pagination; 25 | } 26 | public Meta getMeta() { 27 | return meta; 28 | } 29 | public void setMeta(Meta meta) { 30 | this.meta = meta; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/LocalTimeInterval.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | import java.time.LocalTime; 8 | 9 | public class LocalTimeInterval { 10 | private LocalTime startTime; 11 | private LocalTime endTime; 12 | 13 | public LocalTimeInterval(LocalTime startTime, LocalTime endTime) { 14 | this.startTime = startTime; 15 | this.endTime = endTime; 16 | } 17 | 18 | public static LocalTimeInterval parse(String str) { 19 | String[] parts = str.split("-"); 20 | return new LocalTimeInterval(LocalTime.parse(parts[0]), LocalTime.parse(parts[1])); 21 | } 22 | 23 | public LocalTime getStartTime() { 24 | return startTime; 25 | } 26 | 27 | public void setStartTime(LocalTime startTime) { 28 | this.startTime = startTime; 29 | } 30 | 31 | public LocalTime getEndTime() { 32 | return endTime; 33 | } 34 | 35 | public void setEndTime(LocalTime endTime) { 36 | this.endTime = endTime; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/Meta.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | public class Meta { 8 | private String version; 9 | 10 | public String getVersion() { 11 | return version; 12 | } 13 | 14 | public void setVersion(String version) { 15 | this.version = version; 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/Pagination.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | public class Pagination { 8 | private int offset; 9 | private String nextUrl; 10 | private String previousUrl; 11 | 12 | public int getOffset() { 13 | return offset; 14 | } 15 | 16 | public void setOffset(int offset) { 17 | this.offset = offset; 18 | } 19 | 20 | public String getNextUrl() { 21 | return nextUrl; 22 | } 23 | 24 | public void setNextUrl(String nextUrl) { 25 | this.nextUrl = nextUrl; 26 | } 27 | 28 | public String getPreviousUrl() { 29 | return previousUrl; 30 | } 31 | 32 | public void setPreviousUrl(String previousUrl) { 33 | this.previousUrl = previousUrl; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/RecurringSchedule.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | import java.time.DayOfWeek; 8 | import java.time.LocalDate; 9 | import java.time.LocalTime; 10 | import java.util.Set; 11 | 12 | public class RecurringSchedule { 13 | private LocalDate startDate; 14 | private LocalDate endDate; 15 | private LocalTime dailyStartTime; 16 | private LocalTime dailyEndTime; 17 | private Set days; 18 | 19 | public LocalDate getStartDate() { 20 | return startDate; 21 | } 22 | 23 | public void setStartDate(LocalDate startDate) { 24 | this.startDate = startDate; 25 | } 26 | 27 | public LocalDate getEndDate() { 28 | return endDate; 29 | } 30 | 31 | public void setEndDate(LocalDate endDate) { 32 | this.endDate = endDate; 33 | } 34 | 35 | public LocalTime getDailyStartTime() { 36 | return dailyStartTime; 37 | } 38 | 39 | public void setDailyStartTime(LocalTime dailyStartTime) { 40 | this.dailyStartTime = dailyStartTime; 41 | } 42 | 43 | public LocalTime getDailyEndTime() { 44 | return dailyEndTime; 45 | } 46 | 47 | public void setDailyEndTime(LocalTime dailyEndTime) { 48 | this.dailyEndTime = dailyEndTime; 49 | } 50 | 51 | public Set getDays() { 52 | return days; 53 | } 54 | 55 | public void setDays(Set days) { 56 | this.days = days; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/Restriction.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | import ca.bc.gov.ols.router.open511.enums.Open511RestrictionType; 8 | 9 | public class Restriction { 10 | private Open511RestrictionType restrictionType; 11 | private double value; 12 | 13 | public Open511RestrictionType getRestrictionType() { 14 | return restrictionType; 15 | } 16 | 17 | public void setRestrictionType(Open511RestrictionType restrictionType) { 18 | this.restrictionType = restrictionType; 19 | } 20 | 21 | public double getValue() { 22 | return value; 23 | } 24 | 25 | public void setValue(double value) { 26 | this.value = value; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/Road.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | import java.util.List; 8 | 9 | import ca.bc.gov.ols.router.open511.enums.Direction; 10 | import ca.bc.gov.ols.router.open511.enums.ImpactedSystem; 11 | import ca.bc.gov.ols.router.open511.enums.RoadState; 12 | 13 | public class Road { 14 | private String name; 15 | private String url; 16 | private String from; 17 | private String to; 18 | private RoadState state; 19 | private Direction direction; 20 | private Integer lanesOpen; 21 | private Integer lanesClosed; 22 | private List impactedSystems; 23 | private List restrictions; 24 | private Integer delay; 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | 34 | public String getUrl() { 35 | return url; 36 | } 37 | 38 | public void setUrl(String url) { 39 | this.url = url; 40 | } 41 | 42 | public String getFrom() { 43 | return from; 44 | } 45 | 46 | public void setFrom(String from) { 47 | this.from = from; 48 | } 49 | 50 | public String getTo() { 51 | return to; 52 | } 53 | 54 | public void setTo(String to) { 55 | this.to = to; 56 | } 57 | 58 | public RoadState getState() { 59 | return state; 60 | } 61 | 62 | public void setState(RoadState state) { 63 | this.state = state; 64 | } 65 | 66 | public Direction getDirection() { 67 | return direction; 68 | } 69 | 70 | public void setDirection(Direction direction) { 71 | this.direction = direction; 72 | } 73 | 74 | public Integer getLanesOpen() { 75 | return lanesOpen; 76 | } 77 | 78 | public void setLanesOpen(Integer lanesOpen) { 79 | this.lanesOpen = lanesOpen; 80 | } 81 | 82 | public Integer getLanesClosed() { 83 | return lanesClosed; 84 | } 85 | 86 | public void setLanesClosed(Integer lanesClosed) { 87 | this.lanesClosed = lanesClosed; 88 | } 89 | 90 | public List getImpactedSystems() { 91 | return impactedSystems; 92 | } 93 | 94 | public void setImpactedSystems(List impactedSystems) { 95 | this.impactedSystems = impactedSystems; 96 | } 97 | 98 | public List getRestrictions() { 99 | return restrictions; 100 | } 101 | 102 | public void setRestrictions(List restrictions) { 103 | this.restrictions = restrictions; 104 | } 105 | 106 | public Integer getDelay() { 107 | return delay; 108 | } 109 | 110 | public void setDelay(Integer delay) { 111 | this.delay = delay; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/Schedule.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | import java.util.List; 8 | 9 | import ca.bc.gov.ols.router.open511.enums.ScheduleException; 10 | 11 | public class Schedule { 12 | List recurringSchedules; 13 | List exceptions; 14 | List intervals; 15 | 16 | public List getRecurringSchedules() { 17 | return recurringSchedules; 18 | } 19 | 20 | public void setRecurringSchedules(List recurringSchedules) { 21 | this.recurringSchedules = recurringSchedules; 22 | } 23 | 24 | public List getExceptions() { 25 | return exceptions; 26 | } 27 | 28 | public void setExceptions(List exceptions) { 29 | this.exceptions = exceptions; 30 | } 31 | 32 | public List getIntervals() { 33 | return intervals; 34 | } 35 | 36 | public void setIntervals(List intervals) { 37 | this.intervals = intervals; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/ScheduleInterval.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | import ca.bc.gov.ols.router.time.TemporalSet; 10 | 11 | public class ScheduleInterval implements TemporalSet{ 12 | private LocalDateTime start = null; 13 | private LocalDateTime end = null; 14 | 15 | public ScheduleInterval(LocalDateTime start, LocalDateTime end) { 16 | this.start = start; 17 | this.end = end; 18 | } 19 | 20 | public static ScheduleInterval parse(String str) { 21 | String[] parts = str.split("\\/"); 22 | 23 | LocalDateTime start = LocalDateTime.parse(parts[0]); 24 | LocalDateTime end = null; 25 | if(parts.length > 1) { 26 | end = LocalDateTime.parse(parts[1]); 27 | } 28 | return new ScheduleInterval(start, end); 29 | } 30 | 31 | public LocalDateTime getStart() { 32 | return start; 33 | } 34 | 35 | public void setStart(LocalDateTime start) { 36 | this.start = start; 37 | } 38 | 39 | public LocalDateTime getEnd() { 40 | return end; 41 | } 42 | 43 | public void setEnd(LocalDateTime end) { 44 | this.end = end; 45 | } 46 | 47 | @Override 48 | public boolean contains(LocalDateTime dateTime) { 49 | if((start == null || start.compareTo(dateTime) <= 0) 50 | && (end == null || end.isAfter(dateTime))) { 51 | return true; 52 | } 53 | return false; 54 | } 55 | 56 | @Override 57 | public boolean isAlways() { 58 | if(start == null && end == null) { 59 | return true; 60 | } 61 | return false; 62 | } 63 | 64 | @Override 65 | public LocalDateTime after(LocalDateTime dateTime) { 66 | if(!contains(dateTime)) return dateTime; 67 | return end.plusSeconds(1); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/Direction.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum Direction { 8 | N,NW,W,SW,S,SE,E,NE,NONE,BOTH; 9 | } 10 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/EventCertainty.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum EventCertainty { 8 | OBSERVED, LIKELY, POSSIBLE, UNKNOWN; 9 | } 10 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/EventSeverity.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum EventSeverity { 8 | MINOR, MODERATE, MAJOR, UNKNOWN; 9 | } 10 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/EventStatus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum EventStatus { 8 | ACTIVE, ARCHIVED; 9 | } 10 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/EventSubtype.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum EventSubtype { 8 | ACCIDENT, 9 | SPILL, 10 | OBSTRUCTION, 11 | HAZARD, 12 | ROAD_MAINTENANCE, 13 | ROAD_CONSTRUCTION, 14 | EMERGENCY_MAINTENANCE, 15 | PLANNED_EVENT, 16 | CROWD, 17 | HAIL, 18 | THUNDERSTORM, 19 | HEAVY_DOWNPOUR, 20 | STRONG_WINDS, 21 | BLOWING_DUST, 22 | SANDSTORM, 23 | INSECT_SWARMS, 24 | AVALANCHE_HAZARD, 25 | SURFACE_WATER_HAZARD, 26 | MUD, 27 | LOOSE_GRAVEL, 28 | OIL_ON_ROADWAY, 29 | FIRE, 30 | SIGNAL_LIGHT_FAILURE, 31 | PARTLY_ICY, 32 | ICE_COVERED, 33 | PARTLY_SNOW_PACKED, 34 | SNOW_PACKED, 35 | PARTLY_SNOW_COVERED, 36 | SNOW_COVERED, 37 | DRIFTING_SNOW, 38 | POOR_VISIBILITY, 39 | ALMOST_IMPASSABLE, 40 | PASSABLE_WITH_CARE; 41 | } 42 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/EventType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum EventType { 8 | CONSTRUCTION, SPECIAL_EVENT, INCIDENT, WEATHER_CONDITION, ROAD_CONDITION; 9 | } 10 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/ImpactedSystem.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum ImpactedSystem { 8 | ROAD, SIDEWALK, BIKELANE, PARKING; 9 | } 10 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/Open511RestrictionType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum Open511RestrictionType { 8 | SPEED, WIDTH, HEIGHT, WEIGHT, AXLE_WEIGHT; 9 | } 10 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/RoadState.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | public enum RoadState { 8 | CLOSED, 9 | SOME_LANES_CLOSED, 10 | SINGLE_LANE_ALTERNATING, 11 | ALL_LANES_OPEN; 12 | } 13 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/open511/enums/ScheduleException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.open511.enums; 6 | 7 | import java.time.LocalDate; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import ca.bc.gov.ols.router.open511.LocalTimeInterval; 12 | 13 | public class ScheduleException { 14 | private LocalDate date; 15 | private List times; 16 | 17 | public static ScheduleException parse(String str) { 18 | ScheduleException exc = new ScheduleException(); 19 | String[] parts = str.split("\\s"); 20 | LocalDate date = LocalDate.parse(parts[0]); 21 | List times = new ArrayList(parts.length - 1); 22 | for(int i = 1; i < parts.length; i++) { 23 | times.add(LocalTimeInterval.parse(parts[i])); 24 | } 25 | exc.setDate(date); 26 | exc.setTimes(times); 27 | return exc; 28 | } 29 | 30 | public LocalDate getDate() { 31 | return date; 32 | } 33 | 34 | public void setDate(LocalDate date) { 35 | this.date = date; 36 | } 37 | 38 | public List getTimes() { 39 | return times; 40 | } 41 | 42 | public void setTimes(List times) { 43 | this.times = times; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/restrictions/AbstractRestriction.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.restrictions; 2 | 3 | import org.locationtech.jts.geom.Point; 4 | 5 | import ca.bc.gov.ols.router.data.enums.RestrictionSource; 6 | import ca.bc.gov.ols.router.data.enums.RestrictionType; 7 | 8 | public abstract class AbstractRestriction implements Constraint { 9 | 10 | public final RestrictionSource source; 11 | public final RestrictionType type; 12 | public final Point location; 13 | public final int locationId; 14 | 15 | public AbstractRestriction(RestrictionSource source, RestrictionType type, Point location, int locationId) { 16 | this.source = source; 17 | this.type = type; 18 | this.location = location; 19 | this.locationId = locationId; 20 | } 21 | 22 | @Override 23 | public RestrictionSource getSource() { 24 | return source; 25 | } 26 | 27 | @Override 28 | public RestrictionType getType() { 29 | return type; 30 | } 31 | 32 | @Override 33 | public Point getLocation() { 34 | return location; 35 | } 36 | 37 | public int getLocationId() { 38 | return locationId; 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/restrictions/Constraint.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.restrictions; 2 | 3 | import java.util.List; 4 | 5 | import org.locationtech.jts.geom.Point; 6 | 7 | import ca.bc.gov.ols.router.api.RoutingParameters; 8 | import ca.bc.gov.ols.router.data.enums.RestrictionSource; 9 | import ca.bc.gov.ols.router.data.enums.RestrictionType; 10 | 11 | public interface Constraint { 12 | 13 | /** 14 | * Tests whether the vehicle described in the params cannot pass through this constraint (restriction) at all. 15 | * @param params The route options and vehicle parameters 16 | * @return True if the vehicle described in the params cannot pass through this constraint (restriction) at all 17 | */ 18 | boolean prevents(RoutingParameters params); 19 | 20 | /** 21 | * Tests whether the vehicle described in the params is constrained in some way by this constraint (restriction), eg. must be in certain lane(s), etc. 22 | * @param params The route options and vehicle parameters 23 | * @return True if the vehicle described in the params can pass through this constraint (restriction) only with some special care taken 24 | */ 25 | boolean constrains(RoutingParameters params); 26 | 27 | Point getLocation(); 28 | 29 | RestrictionSource getSource(); 30 | 31 | RestrictionType getType(); 32 | 33 | String getVisDescriptor(); 34 | 35 | List getIds(); 36 | } 37 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/restrictions/LaneBasedRestriction.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.restrictions; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import org.locationtech.jts.geom.Point; 8 | 9 | import ca.bc.gov.ols.router.api.RoutingParameters; 10 | import ca.bc.gov.ols.router.data.enums.RestrictionSource; 11 | import ca.bc.gov.ols.router.data.enums.RestrictionType; 12 | 13 | public class LaneBasedRestriction extends AbstractRestriction { 14 | 15 | public final int[] id; 16 | public final double[] permitableValue; 17 | 18 | LaneBasedRestriction(final int[] id, final RestrictionSource source, final RestrictionType type, 19 | final double[] permitableValue, final Point location, final int locationId) { 20 | super(source, type, location, locationId); 21 | this.id = id; 22 | this.permitableValue = permitableValue; 23 | } 24 | 25 | @Override 26 | public RestrictionSource getSource() { 27 | return source; 28 | } 29 | 30 | @Override 31 | public List getIds() { 32 | return Arrays.stream(id).boxed().collect(Collectors.toList()); 33 | } 34 | 35 | /** 36 | * As long as the vehicle's (height) value is less than the maximum allowable in at least one lane, travel is not prevented. 37 | */ 38 | @Override 39 | public boolean prevents(RoutingParameters params) { 40 | Double value = params.getRestrictionValue(type); 41 | if(value == null) return false; 42 | for(double pv : permitableValue) { 43 | if(value <= pv) { 44 | return false; 45 | } 46 | } 47 | return true; 48 | } 49 | 50 | /** 51 | * If the vehicle's (height) value is higher than allowed in some lane, this restriction constrains travel. 52 | */ 53 | @Override 54 | public boolean constrains(RoutingParameters params) { 55 | Double value = params.getRestrictionValue(type); 56 | if(value == null) return false; 57 | for(double pv : permitableValue) { 58 | if(value > pv) { 59 | return true; 60 | } 61 | } 62 | return false; 63 | } 64 | 65 | public boolean[] getSafeLanes(RoutingParameters params) { 66 | boolean[] safeLanes = new boolean[permitableValue.length]; 67 | double value = params.getRestrictionValue(type); 68 | for(int i = 0; i < permitableValue.length; i++) { 69 | if(value <= permitableValue[i]) { 70 | safeLanes[i] = true; 71 | } else { 72 | safeLanes[i] = false; 73 | } 74 | } 75 | return safeLanes; 76 | } 77 | 78 | @Override 79 | public String getVisDescriptor() { 80 | StringBuilder sb = new StringBuilder("Max "); 81 | sb.append(type.visName).append(": "); 82 | for(int i = 0; i < permitableValue.length; i++) { 83 | sb.append("lane ").append(i+1).append(": ").append(permitableValue[i]).append(" ").append(type.unit).append("; "); 84 | } 85 | sb.append("(").append(source).append(":").append(Arrays.toString(id)).append(")"); 86 | return sb.toString(); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/restrictions/rdm/RdmFetcher.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.restrictions.rdm; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.io.Reader; 7 | import java.net.URL; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import ca.bc.gov.ols.router.config.RouterConfig; 15 | 16 | public class RdmFetcher { 17 | private final static Logger logger = LoggerFactory.getLogger(RdmFetcher.class.getCanonicalName()); 18 | 19 | //private String rdmApiUrl = "https://dev-rdm-public.th.gov.bc.ca/api"; 20 | private String rdmApiUrl = "https://tst-rdm-public.th.gov.bc.ca/api"; 21 | private static final String RESTRICTIONS_ACTIVE_ENDPOINT = "/view/restrictions_active"; 22 | private static final String RESTRICTIONS_DELETED_ENDPOINT = "/view/restrictions_deleted"; 23 | private static final int OFFSET_INCREMENT = 500; 24 | 25 | public RdmFetcher(RouterConfig config) { 26 | rdmApiUrl = config.getRdmApiUrl(); 27 | } 28 | 29 | public List fetchAll(RdmParser parser) throws IOException { 30 | List allRestrictions = new ArrayList(); 31 | int offset = 0; 32 | while(true) { 33 | Reader pageReader = fetchPage(rdmApiUrl + RESTRICTIONS_ACTIVE_ENDPOINT + "?limit=" + OFFSET_INCREMENT + "&offset=" + offset); 34 | offset += OFFSET_INCREMENT; 35 | List restrictions = parser.parseRestrictions(pageReader); 36 | if(restrictions.isEmpty()) { 37 | break; 38 | } 39 | allRestrictions.addAll(restrictions); 40 | } 41 | return allRestrictions; 42 | } 43 | 44 | public List fetchChanges(RdmParser parser) throws IOException { 45 | List changedRestrictions = new ArrayList(); 46 | int offset = 0; 47 | while(true) { 48 | Reader pageReader = fetchPage(rdmApiUrl + RESTRICTIONS_ACTIVE_ENDPOINT + "?limit=" + OFFSET_INCREMENT + "&offset=" + offset + 49 | "&filter=LAST_UPDATE_TIMESTAMP BETWEEN '2024-02-10' AND '9999-12-31'"); 50 | offset += OFFSET_INCREMENT; 51 | List restrictions = parser.parseRestrictions(pageReader); 52 | if(restrictions.isEmpty()) { 53 | break; 54 | } 55 | } 56 | // TODO: should we also fetch the deletes here, or in a separate function? 57 | return changedRestrictions; 58 | } 59 | 60 | private Reader fetchPage(String urlString) throws IOException { 61 | logger.info("Fetching page: {}", urlString); 62 | URL url = new URL(urlString); 63 | // TODO: we might want to allow retrying with a delay, if a connection fails, to allow for a random failure 64 | final BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); 65 | return reader; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/restrictions/rdm/RdmParser.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.restrictions.rdm; 2 | 3 | import java.io.IOException; 4 | import java.io.Reader; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import org.locationtech.jts.geom.GeometryFactory; 9 | import org.locationtech.jts.geom.Point; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import com.google.gson.stream.JsonReader; 14 | import com.google.gson.stream.JsonToken; 15 | 16 | import ca.bc.gov.ols.router.data.enums.RestrictionSource; 17 | import ca.bc.gov.ols.router.data.enums.RestrictionType; 18 | import ca.bc.gov.ols.rowreader.JsonRowReader; 19 | 20 | public class RdmParser { 21 | private final static Logger logger = LoggerFactory.getLogger(RdmParser.class.getCanonicalName()); 22 | 23 | GeometryFactory gf; 24 | 25 | public RdmParser(GeometryFactory gf) { 26 | this.gf = gf; 27 | } 28 | 29 | public List parseRestrictions(Reader reader) throws IOException { 30 | JsonReader jr = new JsonReader(reader); 31 | ArrayList restrictions = new ArrayList(); 32 | int count = 0; 33 | jr.beginArray(); 34 | while(jr.hasNext()) { 35 | Restriction r = parseRestriction(jr); 36 | count++; 37 | if(r != null) { 38 | restrictions.add(r); 39 | } 40 | } 41 | jr.close(); 42 | logger.info("Read {} RDM restrictions from file.", count); 43 | return restrictions; 44 | } 45 | 46 | private Restriction parseRestriction(JsonReader jr) throws IOException { 47 | jr.beginObject(); 48 | RestrictionBuilder rb = Restriction.builder(); 49 | while(jr.hasNext()) { 50 | String name = jr.nextName(); 51 | switch(name) { 52 | case "RESTRICTION_ID": 53 | rb.id(jr.nextInt()); 54 | break; 55 | case "RESTRICTION_TYPE": 56 | rb.type(RestrictionType.convert(jr.nextString())); 57 | break; 58 | case "PERMITABLE_VALUE": 59 | if(jr.peek() == JsonToken.NUMBER) { 60 | rb.permitableValue(jr.nextDouble()); 61 | } else { 62 | jr.skipValue(); 63 | } 64 | break; 65 | case "RESTRICTION_AZIMUTH": 66 | if(jr.peek() == JsonToken.NUMBER) { 67 | rb.azimuth(jr.nextDouble()); 68 | } else { 69 | jr.skipValue(); 70 | } 71 | break; 72 | case "NETWORK_SEGMENT_ID": 73 | rb.segmentId(jr.nextInt()); 74 | break; 75 | case "LANE_NUMBER": 76 | if(jr.peek() == JsonToken.NUMBER) { 77 | rb.laneNumber(jr.nextInt()); 78 | } else { 79 | jr.skipValue(); 80 | } 81 | break; 82 | case "FEATURE_SOURCE_SYSTEM": 83 | JsonToken next = jr.peek(); 84 | if(next == JsonToken.STRING) { 85 | rb.featureSource(jr.nextString()); 86 | } else { 87 | jr.skipValue(); 88 | } 89 | break; 90 | case "LOCATION_ID": 91 | rb.locationId(jr.nextInt()); 92 | break; 93 | case "GEOMETRY": 94 | rb.location((Point)JsonRowReader.parseJsonGeometry(jr, gf)); 95 | break; 96 | default: 97 | jr.skipValue(); 98 | } 99 | } 100 | jr.endObject(); 101 | rb.source(RestrictionSource.RDM); 102 | return rb.build(); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/restrictions/rdm/Restriction.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.restrictions.rdm; 2 | 3 | import java.util.List; 4 | 5 | import ca.bc.gov.ols.router.api.RoutingParameters; 6 | import ca.bc.gov.ols.router.restrictions.AbstractRestriction; 7 | 8 | public class Restriction extends AbstractRestriction { 9 | public final int id; 10 | public final int laneNumber; 11 | public final double permitableValue; 12 | public final int segmentId; 13 | public final double azimuth; 14 | // LaneType laneType; 15 | // LaneSubType laneSubType; 16 | // String publicComment; 17 | 18 | public static RestrictionBuilder builder() { 19 | return new RestrictionBuilder(); 20 | } 21 | 22 | Restriction(RestrictionBuilder rb) { 23 | super(rb.source, rb.type, rb.location, rb.locationId); 24 | this.id = rb.id; 25 | this.permitableValue = rb.permitableValue; 26 | this.segmentId = rb.segmentId; 27 | this.laneNumber = rb.laneNumber; 28 | this.azimuth = rb.azimuth; 29 | } 30 | 31 | @Override 32 | public List getIds() { 33 | return List.of(id); 34 | } 35 | 36 | @Override 37 | public boolean prevents(RoutingParameters params) { 38 | Double value = params.getRestrictionValue(type); 39 | if(value == null) return false; 40 | if(type.hasValue) { 41 | if(value <= permitableValue) return false; 42 | } else { 43 | if(value == 0) return false; 44 | } 45 | return true; 46 | } 47 | 48 | @Override 49 | public boolean constrains(RoutingParameters params) { 50 | return false; 51 | } 52 | 53 | @Override 54 | public String getVisDescriptor() { 55 | if(type.hasValue) { 56 | return "Max " + type.visName + ": " + permitableValue + " " + type.unit + " (" + source + ":" + id + ")"; 57 | } 58 | return type.visName; 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return id + ":" + source + ":" + type + ":" + permitableValue; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/restrictions/rdm/RestrictionBuilder.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.restrictions.rdm; 2 | 3 | import org.locationtech.jts.geom.Point; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import ca.bc.gov.ols.router.data.enums.RestrictionSource; 8 | import ca.bc.gov.ols.router.data.enums.RestrictionType; 9 | 10 | public class RestrictionBuilder { 11 | private final static Logger logger = LoggerFactory.getLogger(RestrictionBuilder.class.getCanonicalName()); 12 | 13 | int id = -1; 14 | RestrictionSource source = null; 15 | RestrictionType type = null; 16 | int laneNumber = -1; 17 | double permitableValue = -1; 18 | int segmentId = -1; 19 | double azimuth = -1; 20 | Point location = null; 21 | int locationId; 22 | 23 | // LaneType laneType; 24 | // LaneSubType laneSubType; 25 | // String publicComment; 26 | // featureSource 27 | 28 | // Call Restriction.builder() to get a RestrictionBuilder 29 | RestrictionBuilder() { 30 | } 31 | 32 | public RestrictionBuilder id(int id) { 33 | this.id = id; 34 | return this; 35 | } 36 | 37 | public RestrictionBuilder source(RestrictionSource source) { 38 | this.source = source; 39 | return this; 40 | } 41 | 42 | public RestrictionBuilder type(RestrictionType type) { 43 | this.type = type; 44 | return this; 45 | } 46 | 47 | public RestrictionBuilder laneNumber(int laneNumber) { 48 | this.laneNumber = laneNumber; 49 | return this; 50 | } 51 | 52 | public RestrictionBuilder permitableValue(double permitableValue) { 53 | this.permitableValue = permitableValue; 54 | return this; 55 | } 56 | 57 | public RestrictionBuilder segmentId(int segmentId) { 58 | this.segmentId = segmentId; 59 | return this; 60 | } 61 | 62 | public RestrictionBuilder location(Point location) { 63 | this.location = location; 64 | return this; 65 | } 66 | 67 | public RestrictionBuilder locationId(int locationId) { 68 | this.locationId = locationId; 69 | return this; 70 | } 71 | 72 | public RestrictionBuilder azimuth(double azimuth) { 73 | this.azimuth = azimuth; 74 | return this; 75 | } 76 | 77 | public RestrictionBuilder featureSource(String nextString) { 78 | // TODO add support for this maybe? 79 | return this; 80 | } 81 | 82 | public Restriction build() { 83 | boolean valid = true; 84 | if(source == null) { 85 | valid = false; 86 | logger.warn("Restriction has no source: RestrictionID: {}", id); 87 | } 88 | if(type.hasValue && permitableValue <= 0) { 89 | valid = false; 90 | logger.warn("Restriction permittable Value <= 0: RestrictionID: {}", id); 91 | } 92 | if(segmentId == -1) { 93 | valid = false; 94 | logger.warn("Restriction with no segmentId: RestrictionID: {}", id); 95 | } 96 | if(laneNumber > 0 && type != RestrictionType.VERTICAL) { 97 | logger.warn("Non-vertical lane-based Restriction: RestrictionId: {}", id); 98 | laneNumber = 0; 99 | } 100 | if(valid) { 101 | return new Restriction(this); 102 | } 103 | return null; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/status/BasicStatusMessage.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.status; 2 | 3 | public class BasicStatusMessage implements StatusMessage { 4 | 5 | protected final String message; 6 | protected final Type type; 7 | 8 | public BasicStatusMessage(Type type, String message) { 9 | this.type = type; 10 | this.message = message; 11 | } 12 | 13 | public Type getType() { 14 | return type; 15 | } 16 | 17 | public String getMessage() { 18 | return message; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return getMessage(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/status/RdmStatusMessage.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.status; 2 | 3 | public class RdmStatusMessage extends BasicStatusMessage { 4 | private final int restrictionId; 5 | 6 | public RdmStatusMessage(int restrictionId, String message) { 7 | super(Type.RDM, message); 8 | this.restrictionId = restrictionId; 9 | } 10 | 11 | public int getRestrictionId() { 12 | return restrictionId; 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/status/StatusMessage.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.status; 2 | 3 | public interface StatusMessage { 4 | 5 | public enum Type {RDM} 6 | 7 | public Type getType(); 8 | 9 | public String getMessage(); 10 | 11 | } 12 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/status/SystemStatus.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.status; 2 | 3 | import java.time.ZonedDateTime; 4 | import java.util.Map; 5 | 6 | import ca.bc.gov.ols.router.config.RouterConfig; 7 | import ca.bc.gov.ols.rowreader.DateType; 8 | 9 | public class SystemStatus { 10 | 11 | public final String version = RouterConfig.VERSION; 12 | public final String gitCommitId = RouterConfig.GIT_COMMIT_ID; 13 | public String dataProcessingTimestamp; 14 | public String roadNetworkTimestamp; 15 | 16 | public String startTimestamp = ""; 17 | 18 | public String rdmLastSuccessfulUpdate = ""; 19 | public String rdmLastFailedUpdate = ""; 20 | public int rdmSuccessfulUpdateCount = 0; 21 | public int rdmFailedUpdateCount = 0; 22 | public int rdmLastRecordCount = 0; 23 | 24 | public void setDates(Map dates) { 25 | if(dates != null) { 26 | dataProcessingTimestamp = String.valueOf(dates.get(DateType.PROCESSING_DATE)); 27 | roadNetworkTimestamp = String.valueOf(dates.get(DateType.ITN_VINTAGE_DATE)); 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/time/Always.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.time; 2 | 3 | import java.time.LocalDateTime; 4 | 5 | public class Always implements TemporalSet { 6 | 7 | @Override 8 | public boolean contains(LocalDateTime dateTime) { 9 | return true; 10 | } 11 | 12 | @Override 13 | public boolean isAlways() { 14 | return true; 15 | } 16 | 17 | @Override 18 | public LocalDateTime after(LocalDateTime dateTime) { 19 | return null; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/time/DateInterval.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.time; 6 | 7 | import java.time.LocalDate; 8 | import java.time.LocalDateTime; 9 | 10 | public class DateInterval implements TemporalSet { 11 | private LocalDate start = null; 12 | private LocalDate end = null; 13 | 14 | public DateInterval(LocalDate start, LocalDate end) { 15 | this.start = start; 16 | this.end = end; 17 | } 18 | 19 | public LocalDate getStart() { 20 | return start; 21 | } 22 | 23 | public void setStart(LocalDate start) { 24 | this.start = start; 25 | } 26 | 27 | public LocalDate getEnd() { 28 | return end; 29 | } 30 | 31 | public void setEnd(LocalDate end) { 32 | this.end = end; 33 | } 34 | 35 | @Override 36 | public boolean contains(LocalDateTime dateTime) { 37 | LocalDate date = dateTime.toLocalDate(); 38 | if((start == null || start.compareTo(date) <= 0) 39 | && (end == null || end.isAfter(date))) { 40 | return true; 41 | } 42 | return false; 43 | } 44 | 45 | @Override 46 | public boolean isAlways() { 47 | if(start == null && end == null) { 48 | return true; 49 | } 50 | return false; 51 | } 52 | 53 | 54 | @Override 55 | public LocalDateTime after(LocalDateTime dateTime) { 56 | if(!contains(dateTime)) return dateTime; 57 | return end.plusDays(1).atStartOfDay(); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/time/DaySet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.time; 6 | 7 | import java.time.DayOfWeek; 8 | import java.time.LocalDateTime; 9 | import java.util.EnumSet; 10 | import java.util.Set; 11 | 12 | public class DaySet implements TemporalSet { 13 | private final Set days; 14 | 15 | public DaySet(Set days) { 16 | this.days = Set.copyOf(days); 17 | } 18 | 19 | @Override 20 | public boolean contains(LocalDateTime dateTime) { 21 | return days.contains(dateTime.getDayOfWeek()); 22 | } 23 | 24 | @Override 25 | public boolean isAlways() { 26 | return EnumSet.allOf(DayOfWeek.class).equals(days); 27 | } 28 | 29 | @Override 30 | public LocalDateTime after(LocalDateTime dateTime) { 31 | if(isAlways()) return null; 32 | while(contains(dateTime)) { 33 | dateTime = dateTime.plusDays(1); 34 | } 35 | return dateTime; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/time/TemporalSet.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.time; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | public interface TemporalSet { 10 | 11 | public static final TemporalSet ALWAYS = new Always(); 12 | 13 | public boolean contains(LocalDateTime dateTime); 14 | 15 | public boolean isAlways(); 16 | 17 | // returns the first date/time that is outside of this set and after the given date 18 | public LocalDateTime after(LocalDateTime dateTime); 19 | 20 | public default TemporalSet and(TemporalSet other) { 21 | return new TemporalSetIntersection(this, other); 22 | } 23 | 24 | public default TemporalSet or(TemporalSet other) { 25 | return new TemporalSetUnion(this, other); 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/time/TemporalSetIntersection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.time; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | public class TemporalSetIntersection implements TemporalSet { 12 | 13 | private List sets; 14 | 15 | public TemporalSetIntersection(TemporalSet ... setArray) { 16 | sets = Arrays.asList(setArray); 17 | } 18 | 19 | @SuppressWarnings("unchecked") 20 | public TemporalSetIntersection(List sets) { 21 | this.sets = (List) sets; 22 | } 23 | 24 | @Override 25 | public boolean contains(LocalDateTime dateTime) { 26 | for(TemporalSet set : sets) { 27 | if(!set.contains(dateTime)) { 28 | return false; 29 | } 30 | } 31 | return true; 32 | } 33 | 34 | @Override 35 | public boolean isAlways() { 36 | for(TemporalSet set : sets) { 37 | if(!set.isAlways()) { 38 | return false; 39 | } 40 | } 41 | return true; 42 | } 43 | 44 | @Override 45 | public LocalDateTime after(LocalDateTime dateTime) { 46 | if(isAlways()) return null; 47 | while(dateTime != null) { 48 | LocalDateTime[] possibles = new LocalDateTime[sets.size()]; 49 | for(int i = 0; i < sets.size(); i++) { 50 | TemporalSet set = sets.get(i); 51 | if(!set.contains(dateTime)) { 52 | return dateTime; 53 | } 54 | possibles[i] = set.after(dateTime); 55 | } 56 | LocalDateTime min = null; 57 | for(LocalDateTime possible : possibles) { 58 | if(possible != null && (min == null || possible.isBefore(min))) { 59 | min = possible; 60 | } 61 | } 62 | dateTime = min; 63 | } 64 | return null; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/time/TemporalSetUnion.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.time; 6 | 7 | import java.time.LocalDateTime; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | public class TemporalSetUnion implements TemporalSet { 12 | 13 | private List sets; 14 | 15 | public TemporalSetUnion(TemporalSet ... setArray) { 16 | sets = Arrays.asList(setArray); 17 | } 18 | 19 | @SuppressWarnings("unchecked") 20 | public TemporalSetUnion(List sets) { 21 | this.sets = (List) sets; 22 | } 23 | 24 | @Override 25 | public boolean contains(LocalDateTime dateTime) { 26 | for(TemporalSet set : sets) { 27 | if(set.contains(dateTime)) { 28 | return true; 29 | } 30 | } 31 | return false; 32 | } 33 | 34 | @Override 35 | public boolean isAlways() { 36 | for(TemporalSet set : sets) { 37 | if(set.isAlways()) { 38 | return true; 39 | } 40 | } 41 | // TODO - need to consider sets that combine to make always 42 | // eg. dayset(weekdays) + dayset(weekends) 43 | // or null -> somedate + somedate -> null 44 | return false; 45 | } 46 | 47 | @Override 48 | public LocalDateTime after(LocalDateTime dateTime) { 49 | if(isAlways()) return null; 50 | boolean changed = true; 51 | while(changed) { 52 | changed = false; 53 | for(TemporalSet set : sets) { 54 | if(set.contains(dateTime)) { 55 | LocalDateTime newDateTime = set.after(dateTime); 56 | if(newDateTime != null) { 57 | dateTime = newDateTime; 58 | } 59 | changed = true; 60 | } 61 | } 62 | } 63 | return dateTime; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/time/WeeklyDateRange.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.time; 6 | 7 | import java.time.DayOfWeek; 8 | import java.util.Set; 9 | 10 | public class WeeklyDateRange { 11 | 12 | private final Set daySet; 13 | private final DateInterval dateRange; 14 | 15 | public WeeklyDateRange(Set daySet, DateInterval dateRange) { 16 | if(daySet == null || dateRange == null) { 17 | throw new IllegalArgumentException("Invalid arguments to create WeeklyDateRange; niether dayCode nor dateRange can be null"); 18 | } 19 | this.daySet = daySet; 20 | this.dateRange = dateRange; 21 | } 22 | 23 | public Set getDaySet() { 24 | return daySet; 25 | } 26 | 27 | public DateInterval getDateRange() { 28 | return dateRange; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/util/Azimuth.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.util; 2 | 3 | import org.locationtech.jts.algorithm.Angle; 4 | import org.locationtech.jts.geom.Coordinate; 5 | import org.locationtech.jts.geom.LineString; 6 | 7 | public class Azimuth { 8 | 9 | /* 10 | * Calculate an azimuth value in decimal degrees for the given lineString based on only its 11 | * start and end points. 12 | * 0 is north, clockwise is positive to 90 east, 180 south, 270 west. 13 | * 14 | * @param ls the LineString to calculate the azimuth for 15 | * @returns azimuth value in [0,360] 16 | */ 17 | public static double azimuth(LineString ls) { 18 | Coordinate startCoord = ls.getCoordinateN(0); 19 | Coordinate endCoord = ls.getCoordinateN(ls.getNumPoints()-1); 20 | double angleRads = Angle.PI_TIMES_2 - (Angle.angle(startCoord, endCoord) - Angle.PI_OVER_2); 21 | return Angle.toDegrees(Angle.normalizePositive(angleRads)); 22 | } 23 | 24 | public static double compareAzimuth(LineString ls, double azimuth) { 25 | double segAzimuth = azimuth(ls); 26 | double diff = Math.abs(segAzimuth - azimuth); 27 | if(diff > 180.0) { 28 | diff = 360.0 - diff; 29 | } 30 | return diff; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/util/GeomParseUtil.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.util; 6 | 7 | import org.locationtech.jts.geom.Coordinate; 8 | import org.locationtech.jts.geom.GeometryFactory; 9 | import org.locationtech.jts.geom.LinearRing; 10 | import org.locationtech.jts.geom.Point; 11 | import org.locationtech.jts.geom.Polygon; 12 | 13 | public class GeomParseUtil { 14 | 15 | public static double[] parseDoubleArray(String in) { 16 | String[] strings = in.split(","); 17 | double[] coords = new double[strings.length]; 18 | for(int i = 0; i < strings.length; i++) { 19 | coords[i] = Double.parseDouble(strings[i]); 20 | } 21 | return coords; 22 | } 23 | 24 | public static Polygon buildBbox(double[] coords, GeometryFactory gf) { 25 | if(coords.length != 4) { 26 | throw new NumberFormatException(); 27 | } 28 | LinearRing ring = gf.createLinearRing(new Coordinate[] { 29 | new Coordinate(coords[0], coords[1]), new Coordinate(coords[0], coords[3]), 30 | new Coordinate(coords[2], coords[3]), new Coordinate(coords[2], coords[1]), 31 | new Coordinate(coords[0], coords[1])}); 32 | return gf.createPolygon(ring, null); 33 | } 34 | 35 | public static Polygon parseBbox(String in, GeometryFactory gf) { 36 | if(in == null) { 37 | throw new NumberFormatException(); 38 | } 39 | double[] coords = parseDoubleArray(in); 40 | return buildBbox(coords, gf); 41 | } 42 | 43 | public static Point parseXy(String in, GeometryFactory gf) { 44 | if(in == null) { 45 | throw new NumberFormatException(); 46 | } 47 | double[] coords = parseDoubleArray(in); 48 | if(coords.length != 2) { 49 | throw new NumberFormatException(); 50 | } 51 | return gf.createPoint(new Coordinate(coords[0], coords[1])); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/util/TimeHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.util; 6 | 7 | public class TimeHelper { 8 | 9 | public static String formatTime(double dblSeconds) { 10 | long seconds = Math.round(dblSeconds); 11 | long minutes = 0; 12 | long hours = 0; 13 | if(seconds > 60) { 14 | minutes = seconds / 60; 15 | seconds = seconds % 60; 16 | } 17 | if(minutes > 60) { 18 | hours = minutes / 60; 19 | minutes = minutes % 60; 20 | } 21 | StringBuilder sb = new StringBuilder(); 22 | if(hours > 0) { 23 | sb.append(hours + " hour"); 24 | if(hours > 1) { 25 | sb.append("s"); 26 | } 27 | if(minutes > 0) { 28 | sb.append(" " + minutes + " minute"); 29 | if(minutes > 1) { 30 | sb.append("s"); 31 | } 32 | } 33 | return sb.toString(); 34 | } 35 | if(minutes > 0) { 36 | sb.append(minutes + " minute"); 37 | if(minutes > 1) { 38 | sb.append("s"); 39 | } 40 | if(seconds > 0) { 41 | sb.append(" " + seconds + " second"); 42 | if(seconds > 1) { 43 | sb.append("s"); 44 | } 45 | } 46 | return sb.toString(); 47 | } 48 | return seconds + " seconds"; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /ols-router-core/src/main/java/ca/bc/gov/ols/router/util/UrlCsvInputSource.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.util; 6 | 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.net.URL; 12 | 13 | import org.onebusaway.csv_entities.CsvInputSource; 14 | 15 | public class UrlCsvInputSource implements CsvInputSource { 16 | 17 | private String baseUrlString; 18 | 19 | public UrlCsvInputSource(String baseUrlString) { 20 | this.baseUrlString = baseUrlString; 21 | } 22 | 23 | public boolean hasResource(String name) throws IOException { 24 | try (InputStream stream = getResource(name)) { 25 | } catch(IOException ioe) { 26 | return false; 27 | } 28 | return true; 29 | } 30 | 31 | public InputStream getResource(String name) throws IOException { 32 | String fileUrlString = baseUrlString + name; 33 | if(fileUrlString.startsWith("file:")) { 34 | return new FileInputStream(new File(fileUrlString.substring(5))); 35 | } 36 | URL fileUrl = new URL(fileUrlString); 37 | return fileUrl.openStream(); 38 | } 39 | 40 | public void close() throws IOException { 41 | // TODO: not sure how to implement this; may not be required 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /ols-router-core/src/main/resources-filtered/app.properties: -------------------------------------------------------------------------------- 1 | app.version=${project.version} -------------------------------------------------------------------------------- /ols-router-core/src/main/resources/bgeo_configuration_parameters.csv: -------------------------------------------------------------------------------- 1 | APP_ID,CONFIG_PARAM_NAME,CONFIG_PARAM_VALUE 2 | ROUTER,copyrightLicenseURI,"http://www.data.gov.bc.ca/local/dbc/docs/license/OGL-vbc2.0.pdf" 3 | ROUTER,copyrightNotice,"Copyright 2015 Province of British Columbia - Open Government License" 4 | ROUTER,disclaimer,"http://www2.gov.bc.ca/gov/content/home/disclaimer" 5 | ROUTER,kmlStylesUrl,"http://delivery.openmaps.gov.bc.ca/kml/router_results_styles.kml" 6 | ROUTER,moreInfoUrl,"http://www.data.gov.bc.ca/dbc/geographic/locate/geocoding.page?" 7 | ROUTER,glossaryBaseUrl,"http://www.data.gov.bc.ca/dbc/geographic/locate/physical_address_geo/glossary_of_terms.page?WT.svl=LeftNav" 8 | ROUTER,privacyStatement,"http://www2.gov.bc.ca/gov/content/home/privacy" 9 | ROUTER,baseSrsCode,"3005" 10 | ROUTER,dataSource.className,"ca.bc.gov.ols.router.datasource.FileRouterDataSource" 11 | ROUTER,dataSource.baseFileUrl,"file:///C:/apps/router/data/" 12 | ROUTER,maxPairs,"1000" 13 | ROUTER,maxRoutePoints,"100" 14 | ROUTER,maxOptimalRoutePoints,"100" 15 | ROUTER,defaultEnableOptions,"tc,xc,tr" 16 | ROUTER,defaultXingCost,"5,7,10,1.5" 17 | ROUTER,defaultTurnCost,"3,1,5,2" 18 | ROUTER,defaultTruckRouteMultiplier,"9" 19 | ROUTER,defaultGlobalDistortionField.TRUCK,"" 20 | ROUTER,defaultGlobalDistortionField.CAR,"" 21 | ROUTER,defaultSnapDistance,1000 22 | ROUTER,defaultSimplifyThreshold,250 23 | ROUTER,rdmUpdateInterval,3600 24 | ROUTER,rdmApiUrl,"https://tst-rdm-public.th.gov.bc.ca/api" 25 | -------------------------------------------------------------------------------- /ols-router-core/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ols-router-core/src/test/java/ca/bc/gov/ols/router/util/AzimuthTest.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.util; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import org.junit.jupiter.api.Test; 6 | import org.locationtech.jts.geom.Coordinate; 7 | import org.locationtech.jts.geom.GeometryFactory; 8 | import org.locationtech.jts.geom.LineString; 9 | 10 | class AzimuthTest { 11 | 12 | GeometryFactory gf = new GeometryFactory(); 13 | 14 | @Test 15 | void testAzimuth() { 16 | assertEquals(0, Azimuth.azimuth(buildLineString(0.0, 1.0)), 0.001); 17 | assertEquals(45, Azimuth.azimuth(buildLineString(1.0, 1.0)), 0.001); 18 | assertEquals(90, Azimuth.azimuth(buildLineString(1.0, 0.0)), 0.001); 19 | assertEquals(135, Azimuth.azimuth(buildLineString(1.0, -1.0)), 0.001); 20 | assertEquals(180, Azimuth.azimuth(buildLineString(0.0, -1.0)), 0.001); 21 | assertEquals(225, Azimuth.azimuth(buildLineString(-1.0, -1.0)), 0.001); 22 | assertEquals(270, Azimuth.azimuth(buildLineString(-1.0, 0.0)), 0.001); 23 | assertEquals(315, Azimuth.azimuth(buildLineString(-1.0, 1.0)), 0.001); 24 | } 25 | 26 | @Test 27 | void testCompareAzimuth() { 28 | // lineString with Azimuth 0 29 | assertEquals(10, Azimuth.compareAzimuth(buildLineString(0.0, 1.0), 10.0), 0.001); 30 | assertEquals(170, Azimuth.compareAzimuth(buildLineString(0.0, 1.0), 190.0), 0.001); 31 | assertEquals(90, Azimuth.compareAzimuth(buildLineString(0.0, 1.0), 90.0), 0.001); 32 | assertEquals(90, Azimuth.compareAzimuth(buildLineString(0.0, 1.0), 270.0), 0.001); 33 | assertEquals(135, Azimuth.compareAzimuth(buildLineString(0.0, 1.0), 225.0), 0.001); 34 | 35 | // lineString with Azimuth 45 36 | assertEquals(180, Azimuth.compareAzimuth(buildLineString(1.0, 1.0), 225.0), 0.001); 37 | assertEquals(5, Azimuth.compareAzimuth(buildLineString(1.0, 1.0), 40.0), 0.001); 38 | 39 | // lineString with Azimuth 225 40 | assertEquals(0, Azimuth.compareAzimuth(buildLineString(-1.0, -1.0), 225.0), 0.001); 41 | assertEquals(175, Azimuth.compareAzimuth(buildLineString(-1.0, -1.0), 40.0), 0.001); 42 | 43 | // lineString with Azimuth 315 44 | assertEquals(25, Azimuth.compareAzimuth(buildLineString(-1.0, 1.0), 340.0), 0.001); 45 | assertEquals(85, Azimuth.compareAzimuth(buildLineString(-1.0, 1.0), 40.0), 0.001); 46 | } 47 | 48 | private LineString buildLineString(double toX, double toY) { 49 | return gf.createLineString(new Coordinate[] {new Coordinate(0, 0), new Coordinate(toX, toY)}); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /ols-router-process/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 4.0.0 10 | 11 | ols-router 12 | ca.bc.gov.ols 13 | 2.4.0-SNAPSHOT 14 | 15 | 16 | ols-router-process 17 | OLS Router Processing 18 | 19 | 20 | 21 | 22 | org.codehaus.mojo 23 | exec-maven-plugin 24 | 1.5.0 25 | 26 | 27 | 28 | exec 29 | 30 | 31 | 32 | 33 | java 34 | 35 | -Xmx3000M 36 | -classpath 37 | 39 | 40 | ca.bc.gov.ols.router.process.RouterProcess 41 | /data/router/ 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ca.bc.gov.ols 51 | ols-router-core 52 | ${project.version} 53 | 54 | 55 | ch.qos.logback 56 | logback-classic 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /ols-router-process/src/main/java/ca/bc/gov/ols/router/process/RpStreetEnd.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.process; 6 | 7 | import ca.bc.gov.ols.enums.TrafficImpactor; 8 | import ca.bc.gov.ols.enums.TravelDirection; 9 | import ca.bc.gov.ols.router.data.WeeklyTimeRange; 10 | import ca.bc.gov.ols.router.data.enums.End; 11 | import ca.bc.gov.ols.router.data.enums.TurnTimeCode; 12 | import ca.bc.gov.ols.router.data.enums.XingClass; 13 | 14 | public class RpStreetEnd implements Comparable { 15 | 16 | private final RpStreetSegment segment; 17 | private final int angle; 18 | private final End end; 19 | 20 | 21 | public RpStreetEnd(RpStreetSegment segment, int angle, End end) { 22 | this.segment = segment; 23 | this.angle = angle; 24 | this.end = end; 25 | } 26 | 27 | public RpStreetSegment getSegment() { 28 | return segment; 29 | } 30 | 31 | public int getAngle() { 32 | return angle; 33 | } 34 | 35 | public End getEnd() { 36 | return end; 37 | } 38 | 39 | public int getIntersectionId() { 40 | if(End.FROM.equals(end)) { 41 | return segment.getStartIntersectionId(); 42 | } 43 | return segment.getEndIntersectionId(); 44 | } 45 | 46 | public TrafficImpactor getTrafficImpactor() { 47 | if(end == End.FROM) { 48 | return segment.getStartTrafficImpactor(); 49 | } 50 | return segment.getEndTrafficImpactor(); 51 | } 52 | 53 | public TravelDirection getTravelDir() { 54 | if(end == End.FROM) { 55 | return segment.getTravelDirection(); 56 | } 57 | return segment.getTravelDirection().flip(); 58 | } 59 | 60 | public void setXingClass(XingClass xingClass) { 61 | segment.setXingClass(end, xingClass); 62 | } 63 | 64 | public TurnTimeCode getLeftTR() { 65 | return segment.getLeftTR(end); 66 | } 67 | 68 | public WeeklyTimeRange getLeftTRTimeRange() { 69 | if(segment.getLeftTR(end) != null) { 70 | return segment.getLeftTR(end).getTimeRange(); 71 | } 72 | return null; 73 | } 74 | 75 | public TurnTimeCode getCentreTR() { 76 | return segment.getCentreTR(end); 77 | } 78 | 79 | public WeeklyTimeRange getCentreTRTimeRange() { 80 | if(segment.getCentreTR(end) != null) { 81 | return segment.getCentreTR(end).getTimeRange(); 82 | } 83 | return null; 84 | } 85 | 86 | public TurnTimeCode getRightTR() { 87 | return segment.getRightTR(end); 88 | } 89 | 90 | public WeeklyTimeRange getRightTRTimeRange() { 91 | if(segment.getRightTR(end) != null) { 92 | return segment.getRightTR(end).getTimeRange(); 93 | } 94 | return null; 95 | } 96 | 97 | public void clearLeftTR() { 98 | if(segment.getLeftTR(end) != null) { 99 | RouterProcess.droppedTRs++; 100 | segment.clearLeftTR(end); 101 | } 102 | } 103 | 104 | public void clearCentreTR() { 105 | if(segment.getCentreTR(end) != null) { 106 | RouterProcess.droppedTRs++; 107 | segment.clearCentreTR(end); 108 | } 109 | } 110 | 111 | public void clearRightTR() { 112 | if(segment.getRightTR(end) != null) { 113 | RouterProcess.droppedTRs++; 114 | segment.clearRightTR(end); 115 | } 116 | } 117 | 118 | public RpStreetEnd getOtherEnd() { 119 | if(End.FROM.equals(end)) { 120 | return segment.getEndEnd(); 121 | } 122 | return segment.getStartEnd(); 123 | } 124 | 125 | @Override 126 | public int compareTo(RpStreetEnd otherEnd) { 127 | return angle - otherEnd.angle; 128 | } 129 | 130 | @Override 131 | public String toString() { 132 | return "Stub:" + angle; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /ols-router-process/src/main/java/ca/bc/gov/ols/router/process/RpStreetIntersection.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.process; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | import org.locationtech.jts.geom.Point; 12 | 13 | public class RpStreetIntersection { 14 | 15 | private int id; 16 | private Point point; 17 | private List streetEnds = null; 18 | 19 | public RpStreetIntersection(int id, Point point) { 20 | this.id = id; 21 | this.point = point; 22 | } 23 | 24 | public int getId() { 25 | return id; 26 | } 27 | 28 | public Point getPoint() { 29 | return point; 30 | } 31 | 32 | public void addEnd(RpStreetEnd end) { 33 | if(streetEnds == null) { 34 | streetEnds = new ArrayList(4); 35 | } 36 | int i; 37 | for(i = 0; i < streetEnds.size() && streetEnds.get(i).getAngle() < end.getAngle(); i++); 38 | streetEnds.add(i, end); 39 | } 40 | 41 | public List getEnds() { 42 | return Collections.unmodifiableList(streetEnds); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/GeotoolsGeometryReprojector.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest; 6 | 7 | import org.geotools.geometry.jts.JTS; 8 | import org.geotools.referencing.CRS; 9 | import org.opengis.referencing.FactoryException; 10 | import org.opengis.referencing.NoSuchAuthorityCodeException; 11 | import org.opengis.referencing.crs.CoordinateReferenceSystem; 12 | import org.opengis.referencing.cs.AxisDirection; 13 | import org.opengis.referencing.operation.MathTransform; 14 | import org.opengis.referencing.operation.TransformException; 15 | 16 | import org.locationtech.jts.geom.Geometry; 17 | import org.locationtech.jts.geom.util.AffineTransformation; 18 | 19 | import ca.bc.gov.ols.router.api.GeometryReprojector; 20 | 21 | public class GeotoolsGeometryReprojector implements GeometryReprojector { 22 | 23 | @Override 24 | public T reproject(T geom, int toSRSCode) { 25 | if(geom == null) { 26 | return null; 27 | } 28 | if(geom.getSRID() == toSRSCode) { 29 | return geom; 30 | } 31 | CoordinateReferenceSystem fromCRS = srsCodeToCRS(geom.getSRID()); 32 | CoordinateReferenceSystem toCRS = srsCodeToCRS(toSRSCode); 33 | 34 | try { 35 | MathTransform transform = CRS.findMathTransform(fromCRS, toCRS); 36 | if(fromCRS.getCoordinateSystem().getAxis(0).getDirection().absolute() 37 | .equals(AxisDirection.NORTH)) { 38 | geom = flipAxes(geom); 39 | } 40 | @SuppressWarnings("unchecked") 41 | T newGeom = (T)JTS.transform(geom, transform); 42 | if(toCRS.getCoordinateSystem().getAxis(0).getDirection().absolute() 43 | .equals(AxisDirection.NORTH)) { 44 | newGeom = flipAxes(newGeom); 45 | } 46 | newGeom.setSRID(toSRSCode); 47 | return newGeom; 48 | } catch(FactoryException fe) { 49 | throw new RuntimeException("Unexpected error in coordinate reprojection.", fe); 50 | } catch(TransformException te) { 51 | throw new RuntimeException("Unexpected error in coordinate reprojection.", te); 52 | } 53 | } 54 | 55 | private static CoordinateReferenceSystem srsCodeToCRS(int srsCode) { 56 | try { 57 | return CRS.decode("EPSG:" + srsCode); 58 | } catch(NoSuchAuthorityCodeException e) { 59 | throw new IllegalArgumentException("Invalid srsCode: \"" + srsCode + "\""); 60 | } catch(FactoryException e) { 61 | throw new RuntimeException("Unexpected error in coordinate reprojection."); 62 | } 63 | } 64 | 65 | private static T flipAxes(T geom) { 66 | AffineTransformation transform = new AffineTransformation(0, 1, 0, 1, 0, 0); 67 | @SuppressWarnings("unchecked") 68 | T newGeom = (T)transform.transform(geom); 69 | newGeom.setSRID(geom.getSRID()); 70 | return newGeom; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/RouterApplication.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest; 6 | 7 | import java.time.Duration; 8 | import java.time.Instant; 9 | 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.boot.SpringApplication; 13 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 14 | import org.springframework.boot.autoconfigure.SpringBootApplication; 15 | import org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration; 16 | import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration; 17 | import org.springframework.context.annotation.Bean; 18 | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 19 | 20 | import ca.bc.gov.ols.router.Router; 21 | import ca.bc.gov.ols.router.RouterFactory; 22 | import ca.bc.gov.ols.router.api.GeometryReprojector; 23 | import ca.bc.gov.ols.router.config.RouterConfig; 24 | 25 | @SpringBootApplication 26 | @EnableAutoConfiguration(exclude = { CassandraAutoConfiguration.class, UserDetailsServiceAutoConfiguration.class }) 27 | public class RouterApplication { 28 | private static final Logger logger = LoggerFactory.getLogger(RouterApplication.class.getCanonicalName()); 29 | 30 | 31 | private Router router; 32 | private GeometryReprojector reprojector = new GeotoolsGeometryReprojector(); 33 | 34 | public static void main(String[] args) { 35 | SpringApplication.run(RouterApplication.class, args); 36 | } 37 | 38 | public RouterApplication(ThreadPoolTaskScheduler taskScheduler) { 39 | logger.info("RouterApplication() constructor called"); 40 | RouterFactory routerFactory = new RouterFactory(); 41 | routerFactory.setGeometryReprojector(reprojector); 42 | router = routerFactory.getRouter(); 43 | RouterConfig config = router.getConfig(); 44 | 45 | taskScheduler.scheduleAtFixedRate(new Runnable() { 46 | 47 | @Override 48 | public void run() { 49 | logger.info("scheduled job running!"); 50 | router.update(); 51 | 52 | } 53 | }, Instant.now(), Duration.ofSeconds(config.getRdmUpdateInterval())); 54 | } 55 | 56 | @Bean 57 | Router router() { 58 | return router; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/SpringSecurityInitializer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest; 6 | 7 | import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; 8 | 9 | public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer { 10 | public SpringSecurityInitializer() { 11 | super(WebSecurityConfig.class); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/ThreadPoolTaskSchedulerConfig.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.rest; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 6 | 7 | @Configuration 8 | public class ThreadPoolTaskSchedulerConfig { 9 | 10 | @Bean 11 | ThreadPoolTaskScheduler threadPoolTaskScheduler() { 12 | ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); 13 | threadPoolTaskScheduler.setPoolSize(2); 14 | threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler"); 15 | return threadPoolTaskScheduler; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/WebSecurityConfig.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest; 6 | 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 10 | import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; 11 | import org.springframework.security.web.SecurityFilterChain; 12 | 13 | @Configuration 14 | @EnableWebSecurity 15 | public class WebSecurityConfig { 16 | 17 | private static final String CSP_POLICY = "script-src 'self' 'unsafe-eval'"; 18 | 19 | @Bean 20 | public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { 21 | http.csrf(csrf -> csrf.disable()) 22 | .authorizeHttpRequests((authorizeHttpRequests) -> 23 | authorizeHttpRequests.anyRequest().permitAll() 24 | ); 25 | 26 | //.headers().and().contentSecurityPolicy(CSP_POLICY); 27 | //.addHeaderWriter(new StaticHeadersWriter("Content-Security-Policy", CSP_POLICY)) 28 | //.and().requestMatchers("/**"); 29 | return http.build(); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/converters/BooleanConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.converters; 6 | 7 | import org.springframework.core.convert.converter.Converter; 8 | 9 | public class BooleanConverter implements Converter { 10 | 11 | @Override 12 | public Boolean convert(String in) { 13 | if(in == null || in.isEmpty()) { 14 | return null; 15 | } else if("0".equals(in) 16 | || "n".equalsIgnoreCase(in) 17 | || "no".equalsIgnoreCase(in) 18 | || "f".equalsIgnoreCase(in) 19 | || "false".equalsIgnoreCase(in)) { 20 | return Boolean.FALSE; 21 | } else if("1".equals(in) 22 | || "y".equalsIgnoreCase(in) 23 | || "yes".equalsIgnoreCase(in) 24 | || "t".equalsIgnoreCase(in) 25 | || "true".equalsIgnoreCase(in)) { 26 | return Boolean.TRUE; 27 | } else { 28 | throw new IllegalArgumentException( 29 | "Parameter must be one of 1, 0, y, n, yes, no, t, f, true, false"); 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/converters/DistanceUnitConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.converters; 6 | 7 | import org.springframework.core.convert.converter.Converter; 8 | 9 | import ca.bc.gov.ols.router.data.enums.DistanceUnit; 10 | 11 | public class DistanceUnitConverter implements Converter { 12 | 13 | @Override 14 | public DistanceUnit convert(String in) { 15 | return DistanceUnit.convert(in); 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/converters/InstantConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.converters; 6 | 7 | import java.time.Instant; 8 | import java.time.format.DateTimeFormatter; 9 | 10 | import org.springframework.core.convert.converter.Converter; 11 | 12 | public class InstantConverter implements Converter { 13 | 14 | @Override 15 | public Instant convert(String in) { 16 | if(in == null || in.isEmpty()) { 17 | return null; 18 | } 19 | return Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse(in)); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/converters/RoutingCriteriaConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.converters; 6 | 7 | import org.springframework.core.convert.converter.Converter; 8 | 9 | import ca.bc.gov.ols.router.data.enums.RoutingCriteria; 10 | 11 | public class RoutingCriteriaConverter implements Converter { 12 | 13 | @Override 14 | public RoutingCriteria convert(String in) { 15 | return RoutingCriteria.convert(in); 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/exceptions/ErrorMessage.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.exceptions; 6 | 7 | import org.springframework.validation.BindingResult; 8 | import org.springframework.validation.FieldError; 9 | import org.springframework.validation.ObjectError; 10 | 11 | public class ErrorMessage { 12 | 13 | private String message; 14 | 15 | public ErrorMessage(String message) { 16 | this.message = message; 17 | } 18 | 19 | public ErrorMessage(BindingResult bindingResult) { 20 | StringBuilder msg = new StringBuilder( 21 | "Invalid parameter values for the following parameters:"); 22 | for(ObjectError error : bindingResult.getAllErrors()) { 23 | if(error instanceof FieldError) { 24 | FieldError fe = (FieldError)error; 25 | msg.append("
Parameter '" + fe.getField() 26 | + "', value '" + fe.getRejectedValue() + "'"); 27 | } else { 28 | msg.append("
" + error.getDefaultMessage()); 29 | } 30 | } 31 | message = msg.toString(); 32 | } 33 | 34 | public String getMessage() { 35 | return message; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/exceptions/ExceptionMapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.exceptions; 6 | 7 | import java.io.PrintWriter; 8 | import java.io.StringWriter; 9 | 10 | import org.springframework.beans.TypeMismatchException; 11 | import org.springframework.http.HttpStatus; 12 | import org.springframework.http.ResponseEntity; 13 | import org.springframework.web.bind.MissingServletRequestParameterException; 14 | import org.springframework.web.bind.annotation.ControllerAdvice; 15 | import org.springframework.web.bind.annotation.ExceptionHandler; 16 | 17 | @ControllerAdvice 18 | public class ExceptionMapper { 19 | 20 | @ExceptionHandler(RuntimeException.class) 21 | public ResponseEntity handleRuntimeException(RuntimeException re) { 22 | StringWriter sw = new StringWriter(); 23 | re.printStackTrace(new PrintWriter(sw)); 24 | String exceptionAsString = sw.toString(); 25 | String message = "Unexpected internal problem: " + re.getMessage() 26 | + "\n" + exceptionAsString; 27 | return new ResponseEntity(new ErrorMessage(message), 28 | HttpStatus.INTERNAL_SERVER_ERROR); 29 | } 30 | 31 | @ExceptionHandler(IllegalArgumentException.class) 32 | public ResponseEntity handleIllegalArgumentException(IllegalArgumentException iae) { 33 | String message = "Invalid parameter: " + iae.getMessage(); 34 | return new ResponseEntity(new ErrorMessage(message), 35 | HttpStatus.BAD_REQUEST); 36 | } 37 | 38 | @ExceptionHandler(MissingServletRequestParameterException.class) 39 | public ResponseEntity handleMissingServletRequestParameterException( 40 | MissingServletRequestParameterException msrpe) { 41 | String message = "Missing parameter " + msrpe.getParameterName() + ": " 42 | + msrpe.getMessage(); 43 | return new ResponseEntity(new ErrorMessage(message), 44 | HttpStatus.BAD_REQUEST); 45 | } 46 | 47 | @ExceptionHandler(TypeMismatchException.class) 48 | public ResponseEntity handleTypeMismatchException( 49 | TypeMismatchException tme) { 50 | String message = "Error in parameter " + tme.getPropertyName() + ": " 51 | + tme.getMessage(); 52 | return new ResponseEntity(new ErrorMessage(message), 53 | HttpStatus.BAD_REQUEST); 54 | } 55 | 56 | @ExceptionHandler(InvalidParameterException.class) 57 | public ResponseEntity handleInvalidParameterException( 58 | InvalidParameterException ipe) { 59 | return new ResponseEntity(ipe.getErrorMessage(), 60 | HttpStatus.BAD_REQUEST); 61 | } 62 | 63 | @ExceptionHandler(NotFoundException.class) 64 | public ResponseEntity handleNotFoundException( 65 | NotFoundException nfe) { 66 | return new ResponseEntity(nfe.getErrorMessage(), 67 | HttpStatus.NOT_FOUND); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/exceptions/InvalidParameterException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.exceptions; 6 | 7 | import org.springframework.validation.BindingResult; 8 | 9 | public class InvalidParameterException extends RuntimeException { 10 | 11 | private static final long serialVersionUID = 1L; 12 | 13 | private ErrorMessage message; 14 | 15 | public InvalidParameterException(BindingResult bindingResult) { 16 | message = new ErrorMessage(bindingResult); 17 | } 18 | 19 | public InvalidParameterException(ErrorMessage message) { 20 | this.message = message; 21 | } 22 | 23 | public ErrorMessage getErrorMessage() { 24 | return message; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/exceptions/NotFoundException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.exceptions; 6 | 7 | public class NotFoundException extends RuntimeException { 8 | 9 | private static final long serialVersionUID = 1L; 10 | 11 | private ErrorMessage errorMessage; 12 | 13 | public NotFoundException(String message) { 14 | errorMessage = new ErrorMessage(message); 15 | } 16 | 17 | public ErrorMessage getErrorMessage() { 18 | return errorMessage; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/messageconverters/html/HtmlErrorMessageConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.messageconverters.html; 6 | 7 | import java.io.IOException; 8 | import java.io.OutputStreamWriter; 9 | import java.io.Writer; 10 | import java.nio.charset.Charset; 11 | 12 | import org.springframework.http.HttpInputMessage; 13 | import org.springframework.http.HttpOutputMessage; 14 | import org.springframework.http.MediaType; 15 | import org.springframework.http.converter.AbstractHttpMessageConverter; 16 | import org.springframework.stereotype.Component; 17 | 18 | import ca.bc.gov.ols.router.rest.exceptions.ErrorMessage; 19 | 20 | /** 21 | * Supports more than just HTML output types, this is the default exception format. 22 | * 23 | * @author chodgson 24 | * 25 | */ 26 | @Component 27 | public class HtmlErrorMessageConverter extends AbstractHttpMessageConverter { 28 | 29 | public HtmlErrorMessageConverter() { 30 | super(MediaType.APPLICATION_XHTML_XML, 31 | MediaType.TEXT_HTML, 32 | new org.springframework.http.MediaType("text", "csv", Charset.forName("UTF-8")), 33 | new org.springframework.http.MediaType("application", "gml+xml", 34 | Charset.forName("UTF-8")), 35 | MediaType.APPLICATION_JSON, 36 | new org.springframework.http.MediaType("application", "javascript", 37 | Charset.forName("UTF-8")), 38 | new org.springframework.http.MediaType("application", "zip", 39 | Charset.forName("UTF-8"))); 40 | } 41 | 42 | @Override 43 | protected boolean supports(Class clazz) { 44 | return ErrorMessage.class.isAssignableFrom(clazz); 45 | } 46 | 47 | @Override 48 | public boolean canRead(Class clazz, MediaType mediaType) { 49 | return false; 50 | } 51 | 52 | @Override 53 | protected ErrorMessage readInternal(Class clazz, 54 | HttpInputMessage inputMessage) throws IOException { 55 | return null; 56 | } 57 | 58 | @Override 59 | protected void writeInternal(ErrorMessage message, HttpOutputMessage outputMessage) 60 | throws IOException { 61 | outputMessage.getHeaders().setContentType(MediaType.TEXT_HTML); 62 | Writer out = new OutputStreamWriter(outputMessage.getBody(), "UTF-8"); 63 | out.write("\r\n\r\n\r\n\r\n"); 64 | 65 | out.write(message.getMessage()); 66 | out.write("\r\n"); 67 | out.flush(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/messageconverters/html/HtmlResponseConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.messageconverters.html; 6 | 7 | import java.io.IOException; 8 | import java.io.OutputStreamWriter; 9 | import java.io.Writer; 10 | 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | import org.springframework.http.HttpInputMessage; 13 | import org.springframework.http.HttpOutputMessage; 14 | import org.springframework.http.MediaType; 15 | import org.springframework.http.converter.AbstractHttpMessageConverter; 16 | import org.springframework.stereotype.Component; 17 | 18 | import ca.bc.gov.ols.router.Router; 19 | import ca.bc.gov.ols.router.api.ApiResponse; 20 | import ca.bc.gov.ols.router.api.RouterDirectionsResponse; 21 | 22 | @Component 23 | public class HtmlResponseConverter extends AbstractHttpMessageConverter { 24 | 25 | @Autowired 26 | private Router router; 27 | 28 | public HtmlResponseConverter() { 29 | super(MediaType.APPLICATION_XHTML_XML, MediaType.TEXT_HTML); 30 | } 31 | 32 | @Override 33 | protected boolean supports(Class clazz) { 34 | return ApiResponse.class.isAssignableFrom(clazz); 35 | } 36 | 37 | @Override 38 | protected RouterDirectionsResponse readInternal( 39 | Class clazz, 40 | HttpInputMessage inputMessage) throws IOException { 41 | return null; 42 | } 43 | 44 | @Override 45 | protected void writeInternal(ApiResponse response, 46 | HttpOutputMessage outputMessage) throws IOException { 47 | Writer out = new OutputStreamWriter(outputMessage.getBody(), "UTF-8"); 48 | HtmlConverterHelper helper = new HtmlConverterHelper(router, out); 49 | helper.convertResponse(response); 50 | out.flush(); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/messageconverters/json/JsonDefaultsResponseConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.messageconverters.json; 6 | 7 | import java.io.IOException; 8 | import java.io.OutputStreamWriter; 9 | import java.io.Writer; 10 | import java.nio.charset.Charset; 11 | import java.util.Arrays; 12 | import java.util.stream.Collectors; 13 | 14 | import org.springframework.http.HttpInputMessage; 15 | import org.springframework.http.HttpOutputMessage; 16 | import org.springframework.http.MediaType; 17 | import org.springframework.http.converter.AbstractHttpMessageConverter; 18 | import org.springframework.stereotype.Component; 19 | 20 | import com.google.gson.stream.JsonWriter; 21 | 22 | import ca.bc.gov.ols.router.api.DefaultsResponse; 23 | import ca.bc.gov.ols.router.config.RouterConfig; 24 | import ca.bc.gov.ols.router.data.enums.RouteOption; 25 | import ca.bc.gov.ols.router.data.enums.VehicleType; 26 | 27 | @Component 28 | public class JsonDefaultsResponseConverter extends AbstractHttpMessageConverter { 29 | 30 | protected JsonDefaultsResponseConverter(MediaType mediaType) { 31 | super(mediaType); 32 | } 33 | 34 | public JsonDefaultsResponseConverter() { 35 | super(new MediaType("application", "vnd.geo+json", 36 | Charset.forName("UTF-8")), MediaType.APPLICATION_JSON); 37 | } 38 | 39 | @Override 40 | protected boolean supports(Class clazz) { 41 | return DefaultsResponse.class.isAssignableFrom(clazz); 42 | } 43 | 44 | @Override 45 | protected DefaultsResponse readInternal( 46 | Class clazz, 47 | HttpInputMessage inputMessage) throws IOException { 48 | return null; 49 | } 50 | 51 | @Override 52 | protected void writeInternal(DefaultsResponse response, 53 | HttpOutputMessage outputMessage) throws IOException { 54 | Writer out = new OutputStreamWriter(outputMessage.getBody(), "UTF-8"); 55 | RouterConfig config = RouterConfig.getInstance(); 56 | 57 | @SuppressWarnings("resource") 58 | JsonWriter jw = new JsonWriter(out); 59 | jw.beginObject(); 60 | 61 | jw.name("version"); 62 | jw.value(RouterConfig.VERSION); 63 | 64 | jw.name("defaultTruckRouteMultiplier"); 65 | jw.value(config.getDefaultTruckRouteMultiplier()); 66 | 67 | jw.name("enableOptions"); 68 | jw.beginArray(); 69 | for(RouteOption ro : response.getEnabledOptions()) { 70 | jw.value(ro.toString()); 71 | } 72 | jw.endArray(); 73 | 74 | jw.name("globalDistortionField"); 75 | jw.beginObject(); 76 | 77 | jw.name("CAR"); 78 | JsonConverterHelper.outputMap(jw, response.getGlobalDistortionField(VehicleType.CAR).toMap(VehicleType.CAR)); // globalDistortionField.CAR 79 | 80 | jw.name("TRUCK"); 81 | JsonConverterHelper.outputMap(jw, response.getGlobalDistortionField(VehicleType.TRUCK).toMap(VehicleType.TRUCK)); // globalDistortionField.CAR 82 | 83 | jw.endObject(); // globalDistortionField 84 | 85 | jw.name("xingCost"); 86 | jw.value(joinArray(config.getDefaultXingCost())); 87 | 88 | jw.name("turnCost"); 89 | jw.value(joinArray(config.getDefaultTurnCost())); 90 | 91 | jw.name("simplifyThreshold"); 92 | jw.value(config.getDefaultSimplifyThreshold()); 93 | 94 | jw.endObject(); //wrapper 95 | out.flush(); 96 | } 97 | 98 | private String joinArray(double[] a) { 99 | return Arrays.stream(a).boxed().map(n -> Double.toString(n)).collect(Collectors.joining(",")); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/messageconverters/json/JsonResponseConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.messageconverters.json; 6 | 7 | import java.io.IOException; 8 | import java.io.OutputStreamWriter; 9 | import java.io.Writer; 10 | import java.nio.charset.Charset; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.http.HttpInputMessage; 14 | import org.springframework.http.HttpOutputMessage; 15 | import org.springframework.http.MediaType; 16 | import org.springframework.http.converter.AbstractHttpMessageConverter; 17 | import org.springframework.stereotype.Component; 18 | 19 | import ca.bc.gov.ols.router.Router; 20 | import ca.bc.gov.ols.router.api.ApiResponse; 21 | 22 | @Component 23 | public class JsonResponseConverter extends AbstractHttpMessageConverter { 24 | 25 | @Autowired 26 | private Router router; 27 | 28 | protected JsonResponseConverter(MediaType mediaType) { 29 | super(mediaType); 30 | } 31 | 32 | public JsonResponseConverter() { 33 | super(new MediaType("application", "vnd.geo+json", 34 | Charset.forName("UTF-8")), MediaType.APPLICATION_JSON); 35 | } 36 | 37 | @Override 38 | protected boolean supports(Class clazz) { 39 | return ApiResponse.class.isAssignableFrom(clazz); 40 | } 41 | 42 | @Override 43 | protected ApiResponse readInternal( 44 | Class clazz, 45 | HttpInputMessage inputMessage) throws IOException { 46 | return null; 47 | } 48 | 49 | @Override 50 | protected void writeInternal(ApiResponse response, 51 | HttpOutputMessage outputMessage) throws IOException { 52 | Writer out = new OutputStreamWriter(outputMessage.getBody(), "UTF-8"); 53 | JsonConverterHelper helper = new JsonConverterHelper(router, out); 54 | helper.convertResponse(response); 55 | out.flush(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/messageconverters/json/JsonpConverterHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.messageconverters.json; 6 | 7 | import java.io.IOException; 8 | import java.io.Writer; 9 | 10 | import ca.bc.gov.ols.router.Router; 11 | import ca.bc.gov.ols.router.api.ApiResponse; 12 | 13 | public class JsonpConverterHelper extends JsonConverterHelper { 14 | 15 | public JsonpConverterHelper(Router router, Writer out) { 16 | super(router, out); 17 | } 18 | 19 | protected void writeHeader(ApiResponse response) throws IOException { 20 | out.write(response.getCallback() + "({"); 21 | } 22 | 23 | protected void writeFooter(ApiResponse response) throws IOException { 24 | out.write("});"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/messageconverters/json/JsonpResponseConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.messageconverters.json; 6 | 7 | import java.io.IOException; 8 | import java.io.OutputStreamWriter; 9 | import java.io.Writer; 10 | import java.nio.charset.Charset; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.http.HttpOutputMessage; 14 | import org.springframework.http.MediaType; 15 | import org.springframework.stereotype.Component; 16 | 17 | import ca.bc.gov.ols.router.Router; 18 | import ca.bc.gov.ols.router.api.ApiResponse; 19 | 20 | @Component 21 | public class JsonpResponseConverter extends JsonResponseConverter { 22 | 23 | @Autowired 24 | private Router router; 25 | 26 | public JsonpResponseConverter() { 27 | super(new MediaType("application", "javascript", 28 | Charset.forName("UTF-8"))); 29 | } 30 | 31 | @Override 32 | protected void writeInternal(ApiResponse response, 33 | HttpOutputMessage outputMessage) throws IOException { 34 | Writer out = new OutputStreamWriter(outputMessage.getBody(), "UTF-8"); 35 | JsonpConverterHelper helper = new JsonpConverterHelper(router, out); 36 | helper.convertResponse(response); 37 | out.flush(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/messageconverters/kml/KmlErrorMessageConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.messageconverters.kml; 6 | 7 | import java.io.IOException; 8 | import java.io.OutputStreamWriter; 9 | import java.io.Writer; 10 | import java.nio.charset.Charset; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.http.HttpInputMessage; 14 | import org.springframework.http.HttpOutputMessage; 15 | import org.springframework.http.MediaType; 16 | import org.springframework.http.converter.AbstractHttpMessageConverter; 17 | import org.springframework.stereotype.Component; 18 | 19 | import ca.bc.gov.ols.router.Router; 20 | import ca.bc.gov.ols.router.config.RouterConfig; 21 | import ca.bc.gov.ols.router.rest.exceptions.ErrorMessage; 22 | 23 | @Component 24 | public class KmlErrorMessageConverter extends AbstractHttpMessageConverter { 25 | 26 | @Autowired 27 | private Router router; 28 | 29 | public KmlErrorMessageConverter() { 30 | super(new MediaType("application", "vnd.google-earth.kml+xml", 31 | Charset.forName("UTF-8"))); 32 | } 33 | 34 | @Override 35 | protected boolean supports(Class clazz) { 36 | return ErrorMessage.class.isAssignableFrom(clazz); 37 | } 38 | 39 | @Override 40 | public boolean canRead(Class clazz, MediaType mediaType) { 41 | return false; 42 | } 43 | 44 | @Override 45 | protected ErrorMessage readInternal(Class clazz, 46 | HttpInputMessage inputMessage) throws IOException { 47 | return null; 48 | } 49 | 50 | @Override 51 | protected void writeInternal(ErrorMessage message, HttpOutputMessage outputMessage) 52 | throws IOException { 53 | Writer out = new OutputStreamWriter(outputMessage.getBody(), "UTF-8"); 54 | RouterConfig config = router.getConfig(); 55 | out.write("\r\n" 56 | + "\r\n"); 58 | 59 | out.write(errorMessageToKML(message, config)); 60 | out.write(""); 61 | //out.flush(); 62 | } 63 | 64 | static String errorMessageToKML(ErrorMessage message, RouterConfig config) { 65 | return "\r\n" 66 | + "Error Message\r\n" 67 | + "1\r\n" 68 | + "\r\n" 69 | + "" + message.getMessage() 70 | + "\r\n" 71 | + "\r\n" 72 | + "" + config.getKmlStylesUrl() 73 | + "#error_message\r\n" 74 | + "\r\n"; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /ols-router-web/src/main/java/ca/bc/gov/ols/router/rest/messageconverters/kml/KmlResponseConverter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2008-2019, Province of British Columbia 3 | * All rights reserved. 4 | */ 5 | package ca.bc.gov.ols.router.rest.messageconverters.kml; 6 | 7 | import java.io.IOException; 8 | import java.io.OutputStreamWriter; 9 | import java.io.Writer; 10 | import java.nio.charset.Charset; 11 | 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.http.HttpInputMessage; 14 | import org.springframework.http.HttpOutputMessage; 15 | import org.springframework.http.MediaType; 16 | import org.springframework.http.converter.AbstractHttpMessageConverter; 17 | import org.springframework.stereotype.Component; 18 | 19 | import ca.bc.gov.ols.router.Router; 20 | import ca.bc.gov.ols.router.api.ApiResponse; 21 | import ca.bc.gov.ols.router.api.RouterDirectionsResponse; 22 | 23 | @Component 24 | public class KmlResponseConverter extends AbstractHttpMessageConverter { 25 | 26 | @Autowired 27 | private Router router; 28 | 29 | public KmlResponseConverter() { 30 | super(new MediaType("application", "vnd.google-earth.kml+xml", 31 | Charset.forName("UTF-8"))); 32 | } 33 | 34 | @Override 35 | protected boolean supports(Class clazz) { 36 | return ApiResponse.class.isAssignableFrom(clazz); 37 | } 38 | 39 | @Override 40 | protected RouterDirectionsResponse readInternal( 41 | Class clazz, 42 | HttpInputMessage inputMessage) throws IOException { 43 | return null; 44 | } 45 | 46 | @Override 47 | protected void writeInternal(ApiResponse response, 48 | HttpOutputMessage outputMessage) throws IOException { 49 | Writer out = new OutputStreamWriter(outputMessage.getBody(), "UTF-8"); 50 | KmlConverterHelper helper = new KmlConverterHelper(router, out); 51 | helper.convertResponse(response); 52 | out.flush(); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /ols-router-web/src/test/java/ca/bc/gov/ols/router/rest/controllers/RoutingControllerTest.java: -------------------------------------------------------------------------------- 1 | package ca.bc.gov.ols.router.rest.controllers; 2 | 3 | import ca.bc.gov.ols.router.Router; 4 | import ca.bc.gov.ols.router.RouterFactory; 5 | import ca.bc.gov.ols.router.api.RouterDistanceBetweenPairsResponse; 6 | import ca.bc.gov.ols.router.api.RoutingParameters; 7 | import ca.bc.gov.ols.router.data.enums.DistanceUnit; 8 | import ca.bc.gov.ols.router.data.enums.RoutingCriteria; 9 | import org.junit.jupiter.api.BeforeEach; 10 | import org.junit.jupiter.api.Tag; 11 | import org.junit.jupiter.api.Test; 12 | import org.mockito.InjectMocks; 13 | import org.mockito.Mock; 14 | import org.mockito.MockitoAnnotations; 15 | import org.springframework.http.HttpStatus; 16 | import org.springframework.http.ResponseEntity; 17 | import org.springframework.validation.BindingResult; 18 | 19 | import java.lang.reflect.Field; 20 | 21 | import static org.junit.jupiter.api.Assertions.assertEquals; 22 | 23 | class RoutingControllerTest { 24 | private Router router; 25 | 26 | @Mock 27 | BindingResult res; 28 | 29 | @InjectMocks 30 | private RoutingController ctrlr; 31 | 32 | @BeforeEach 33 | public void setup() throws Exception { 34 | MockitoAnnotations.openMocks(this); 35 | RouterFactory factory = new RouterFactory(); 36 | factory.setUnitTestMode("TRUE"); 37 | router = factory.getRouter(); 38 | setPrivateField(ctrlr, "router", router); 39 | } 40 | 41 | @Tag("Prod") 42 | @Test 43 | void pingTest() { 44 | ResponseEntity resp = ctrlr.ping(); 45 | assertEquals(resp.getStatusCode(), HttpStatus.OK); 46 | } 47 | 48 | @Tag("Prod") 49 | @Test 50 | void betweenPairsTest() { 51 | RoutingParameters params = new RoutingParameters(); 52 | double fromPts[] = new double[] {100, 100}; 53 | double toPts[] = new double[] {200, 200, 1000, 1000}; 54 | params.setToPoints(toPts); 55 | params.setFromPoints(fromPts); 56 | params.setOutputSRS(3005); 57 | params.setCriteria(RoutingCriteria.SHORTEST); 58 | params.setDistanceUnit(DistanceUnit.KILOMETRE); 59 | params.setCorrectSide(false); 60 | params.setDisable("sc,tf,ev,td"); 61 | params.setRouteDescription("Routing_results"); 62 | RouterDistanceBetweenPairsResponse resp = ctrlr.distanceBetweenPairs(params, res); 63 | assertEquals(resp.getDistanceStr(0), "0.141"); 64 | assertEquals(resp.getDistanceStr(1), "-1"); 65 | assertEquals(resp.getError(0), null); 66 | assertEquals(resp.getError(1), "No Route Found."); 67 | } 68 | 69 | public static void setPrivateField(Object target, String fieldName, Object value){ 70 | try { 71 | Field privateField = target.getClass().getDeclaredField(fieldName); 72 | privateField.setAccessible(true); 73 | privateField.set(target, value); 74 | } catch(Exception e){ 75 | throw new RuntimeException(e); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # ols-router 2 | ![img](https://img.shields.io/badge/Lifecycle-Stable-97ca00) 3 | -------------------------------------------------------------------------------- /src/assembly/license-header.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | license-header 11 | 12 | zip 13 | 14 | false 15 | 16 | 17 | ${project.basedir}/src/license 18 | 19 | 20 | license-header.txt 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/license/license-header.txt: -------------------------------------------------------------------------------- 1 | Copyright ${years}, ${owner} 2 | All rights reserved. 3 | --------------------------------------------------------------------------------