Routing to restricted area

I’m trying to setup self-hosted ORS. Mostly it works fine, but I have found an unexpected behaviour when compared to your demo website. It seems that the problem is destination in restricted access area.

Your service provides a route to the closest possible point: https://maps.openrouteservice.org/directions?n1=50.064011&n2=22.028567&n3=18&a=50.294603,21.439535,50.063806,22.028875&b=0&c=0&k1=en-US&k2=km

My service for the same request:

{"preference":"recommended","language":"en-US","instructions":false,"geometry":true,"elevation":true,"coordinates":[[21.439535,50.294603],[22.028875,50.063806]]}

responds with:

{"error":{"code":2009,"message":"Route could not be found - Unable to find a route between points 1 (21.4395350 50.2946030) and 2 (22.0288750 50.0638060)."},"info":{"engine":{"version":"6.3.0","build_date":"2020-10-16T11:13:23Z"},"timestamp":1602846914237}}

I’ve tested it with both “car” and “hgv” profiles. The result is the same. The behaviour from your demo website is good, how can I configure my service to get similar result?

By the way: in case of a matrix request it returns 0 as a distance. Shouldn’t it be null?

My configuration file:

{
  "ors": {
    "services": {
      "isochrones": {
        "enabled": false
      },
      "mapmatching": {
        "enabled": false
      },
      "matrix": {
        "enabled": true,
        "maximum_routes": 10000,
        "maximum_routes_flexible": 25,
        "maximum_search_radius": 5000,
        "maximum_visited_nodes": 1000000,
        "allow_resolve_locations": false,
        "attribution": "openrouteservice.org, OpenStreetMap contributors"
      },
      "routing": {
        "enabled": true,
        "mode": "normal",
        "routing_name": "openrouteservice routing",
        "sources": [
          "data/osm_file.pbf"
        ],
        "init_threads": 4,
        "attribution": "openrouteservice.org, OpenStreetMap contributors",
        "elevation_preprocessed": false,
        "profiles": {
          "active": [
            "car", "hgv"
          ],
          "default_params": {
            "encoder_flags_size": 8,
            "graphs_root_path": "data/graphs",
            "elevation": false,
            "elevation_provider": "multi",
            "elevation_cache_path": "data/elevation_cache",
            "elevation_cache_clear": false,
            "instructions": false,
            "maximum_distance": 10000000,
            "maximum_distance_dynamic_weights": 10000000,
            "maximum_distance_avoid_areas": 1000000,
            "maximum_waypoints": 200,
            "maximum_snapping_radius": 10000,
            "maximum_avoid_polygon_area": 200000000,
            "maximum_avoid_polygon_extent": 20000,
            "maximum_distance_alternative_routes": 10000000,
            "maximum_alternative_routes": 0,
            "maximum_distance_round_trip_routes": 20000000,
            "maximum_speed_lower_bound": 80,
            "preparation": {
              "min_network_size": 200,
              "min_one_way_network_size": 200,
            },
            "execution": {
              "methods": {
                "ch": {
                  "disabling_allowed": true
                },
                "lm": {
                  "disabling_allowed": true,
                  "active_landmarks": 8
                },
                "core": {
                  "disabling_allowed": true,
                  "active_landmarks": 8
                }
              }
            }
          },
          "profile-car": {
            "profiles": "driving-car",
            "parameters": {
              "encoder_options": "turn_costs=true|block_fords=false|use_acceleration=false",
              "preparation": {
                "methods": {
                  "ch": {
                    "enabled": true,
                    "threads": 4,
                    "weightings": "fastest"
                  },
                  "lm": {
                    "enabled": false,
                    "threads": 4,
                    "weightings": "fastest,shortest",
                    "landmarks": 16
                  },
                  "core": {
                      "enabled": true,
                      "threads": 4,
                      "weightings": "fastest,shortest",
                      "landmarks": 64,
                      "lmsets": "highways;allow_all"
                  }
                }
              },
              "ext_storages": {
                "WayCategory": {},
                "HeavyVehicle": {},
                "WaySurfaceType": {},
                "RoadAccessRestrictions": {
                  "use_for_warnings": true
                }
              }
            }
          },
          "profile-hgv": {
            "profiles": "driving-hgv",
            "parameters": {
              "encoder_options": "turn_costs=true|block_fords=false|use_acceleration=false",
              "preparation": {
                "methods": {
                  "ch": {
                    "enabled": true,
                    "threads": 4,
                    "weightings": "recommended"
                  },
                  "lm": {
                    "enabled": true,
                    "threads": 4,
                    "weightings": "recommended,shortest",
                    "landmarks": 16
                  },
                  "core": {
                    "enabled": true,
                    "threads": 4,
                    "weightings": "recommended,shortest",
                    "landmarks": 64,
                    "lmsets": "highways;allow_all"
                  }
                }
              },
              "ext_storages": {
                "WayCategory": {},
                "HeavyVehicle": {
                  "restrictions": true
                },
                "WaySurfaceType": {}
              }
            }
          },
        }
      }
    },
    "logging": {
      "enabled": true,
      "level_file": "DEBUG_LOGGING.json",
      "location": "/var/log/ors",
      "stdout": true
    },
    "system_message": []
  }
}

Does it work fine for a different destination point that is not in the restricted area? In case you have it set up locally via some console, there should be some output generated there as to why exactly the route could not be found. Do you have this information? Should give more insight.

Yes, it works when I move the point a little bit:

https://maps.openrouteservice.org/directions?n1=50.06154&n2=22.031032&n3=16&a=50.294603,21.439535,50.058943,22.023833&b=0&c=0&k1=en-US&k2=km

For

{"preference":"recommended","language":"en-US","instructions":false,"geometry":true,"elevation":true,"coordinates":[[21.439535,50.294603],[22.023833,50.058943]]}

it works fine.

From server logs:

16 Oct 11:59:15 ERROR [errors.CommonResponseEntityExceptionHandler] - Exception
org.heigit.ors.exceptions.RouteNotFoundException: Route could not be found - Unable to find a route between points 4 (21.6745780 50.5744150) and 5 (22.0288868 50.0638471).
        at org.heigit.ors.routing.RoutingProfileManager.computeLinearRoute(RoutingProfileManager.java:370) ~[classes/:6.3.0]
        at org.heigit.ors.routing.RoutingProfileManager.computeRoute(RoutingProfileManager.java:306) ~[classes/:6.3.0]
        at org.heigit.ors.api.requests.routing.RouteRequestHandler.generateRouteFromRequest(RouteRequestHandler.java:53) ~[classes/:6.3.0]
        at org.heigit.ors.api.controllers.RoutingAPI.getGeoJsonRoute(RoutingAPI.java:159) ~[classes/:6.3.0]
        at jdk.internal.reflect.GeneratedMethodAccessor134.invoke(Unknown Source) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [servlet-api.jar:?]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) [spring-webmvc-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [servlet-api.jar:?]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-websocket.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.heigit.ors.servlet.filters.StatusCodeHandlerFilter.doFilter(StatusCodeHandlerFilter.java:43) [classes/:6.3.0]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.heigit.ors.servlet.filters.CompressionFilter.doFilter(CompressionFilter.java:37) [classes/:6.3.0]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.apache.catalina.filters.CorsFilter.handleSimpleCORS(CorsFilter.java:271) [catalina.jar:8.5.39]
        at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:162) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:130) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
        at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:66) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
        at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:105) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:123) [spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.8.RELEASE.jar:5.0.8.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [catalina.jar:8.5.39]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [catalina.jar:8.5.39]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [catalina.jar:8.5.39]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [catalina.jar:8.5.39]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:493) [catalina.jar:8.5.39]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) [catalina.jar:8.5.39]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [catalina.jar:8.5.39]
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:660) [catalina.jar:8.5.39]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [catalina.jar:8.5.39]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [catalina.jar:8.5.39]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:798) [tomcat-coyote.jar:8.5.39]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-coyote.jar:8.5.39]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:806) [tomcat-coyote.jar:8.5.39]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1498) [tomcat-coyote.jar:8.5.39]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:8.5.39]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:8.5.39]
        at java.lang.Thread.run(Thread.java:834) [?:?]

Thanks. I am having a look at it. Cannot tell from the status right now what the problem is.

I’ve found another difference between my local instance and your official demo:

directions?n1=50.106928&n2=20.178452&n3=10&a=50.011269,20.870247,50.240069,19.159813&b=0&c=0&k1=en-US&k2=km

directions?n1=50.106928&n2=20.178452&n3=10&a=50.011269,20.870247,50.240069,19.159813&b=0&l6=1&c=0&k1=en-US&k2=km

(for some reason the system does not allow me to post links to your maps host)

Your map properly avoids tollways, but my local instance is ignoring this parameter. However it properly avoids highways. Maybe "lmsets": "highways;allow_all" causes the problem? I cannot find any description of this property, but GitHub wiki example proposes something like that: "highways,tollways;highways;tollways;country_193;allow_all".

I am unable to reproduce either of the two errors.
I have used the poland osm file and your configuration. I get proper destination points for the first case and I get an avoided tollroad in the second case.
The lmsets parameter should only make finding routes where tollroads are avoided faster, but it does not change correctness.
Are you sure you are using an up-to-date osm file?

Yes, I download it from Geofabrik every time.

In the second case I’ve regenerated the data with "lmsets": "highways,tollways;highways;tollways;country_193;allow_all" and it fixed my problem - now it avoids tolls. It’s interesting why it was not working before that.

In the first case it still cannot find a valid route. I’m using multiple osm files (Germany, Poland, etc.) merged with osmosis:

osmosis \
belgium-latest.osm.pbf nord-pas-de-calais-latest.osm.pbf germany-latest.osm.pbf great-britain-latest.osm.pbf ireland-and-northern-ireland-latest.osm.pbf isle-of-man-latest.osm.pbf liechtenstein-latest.osm.pbf luxembourg-latest.osm.pbf netherlands-latest.osm.pbf poland-latest.osm.pbf \
--merge --merge --merge --merge --merge --merge --merge --merge --merge \
--wb /var/lib/docker/volumes/ors_data/_data/osm_file.pbf

Do you think it may be the reason? I’ll try to use plain Poland file and check this again.

EDIT: I’ve tested it and it still does not work with the original Poland osm file, so I’ve no idea what is wrong.

I’ve found what is the reason of the first problem.

It seems that min_network_size and min_one_way_network_size set as follows does not work.

{
  "ors": {
    "services": {
      "routing": {
        "profiles": {
          "default_params": {
            "preparation": {
              "min_network_size": 200,
              "min_one_way_network_size": 200,
            },

I’ve moved these two parameters into profile parameters and now it works fine.

{
  "ors": {
    "services": {
      "routing": {
        "profiles": {
          "profile-car": {
            "parameters": {
              "preparation": {
                "min_network_size": 200,
                "min_one_way_network_size": 200,
              },

I think it should work properly with both versions, doesn’t it?