itinero / routing

The routing core of itinero.
Apache License 2.0
222 stars 70 forks source link

fixes IndexOutOfRangeException for ways which don't end in a core node #277

Closed maarno closed 5 years ago

maarno commented 5 years ago

I ran into a problem with Itinero crashing when tagging some ways:

System.IndexOutOfRangeException
  HResult=0x80131508
  Message=Index was outside the bounds of the array.
  Source=Itinero.IO.Osm
  StackTrace:
   at Itinero.IO.Osm.Streams.RouterDbStreamTarget.AddWay(Way way)
   at OsmSharp.Streams.OsmStreamTarget.DoPull(Boolean ignoreNodes, Boolean ignoreWays, Boolean ignoreRelations)
   at Itinero.IO.Osm.Streams.RouterDbStreamTarget.OnBeforePull()
   at OsmSharp.Streams.OsmStreamTarget.Pull()
   at Itinero.IO.Osm.RouterDbExtensions.LoadOsmData(RouterDb db, OsmStreamSource[] sources, LoadSettings settings, Vehicle[] vehicles)

This little change fixes it.

xivk commented 5 years ago

Can you give an example of the ways this fails on? It's a bit strange this bug pops up now. I have used Itinero before to process the entire planet (doing that right).

It this after taking an extract or something with nodes missing?

maarno commented 5 years ago

we haven't had this problem before either. It only showed up when we added tags to ways using a custom implementation of the ITwoPassProcessor. It's related to this ticket: https://github.com/itinero/routing/issues/19

            using (var stream = new FileInfo(mapNameFullPath).OpenRead())
            {
                routerDb = new RouterDb();
                routerDb.LoadOsmData(stream,
                    new LoadSettings()
                    {
                        Processors = new List<ITwoPassProcessor>() 
                        {
                            new RestrictedAreasProcessor(restrictedZones)
                        },
                    },
                    profiles.ToArray()
                );
            }

In the RestrictedAreasProcessor we add tags to the way:

        public void SecondPass(Way way)
        {
            foreach (var n in way.Nodes)
            {
                if (_nodeTags.TryGetValue(n, out var tag))
                {
                    way.Tags.AddOrReplace(tag);
                }
            }
        }

we can define certain areas as restricted using polygons in WKT format. I suspect that the polygon which surfaced the problem might cut a defined way in the middle?! That's the area: POLYGON((106.78358289544055 -6.133699250072027,106.79079267327256 -6.15452163978577,106.78529950921008 -6.16783388774256,106.78976270501084 -6.178073851072725,106.79388257805772 -6.185583031629719,106.7990324193663 -6.2104990931701565,106.81963178460067 -6.235072683905457,106.84160444085069 -6.247359047771226,106.86495038811631 -6.247017763777947,106.88314649407333 -6.2517957194284435,106.89378949944444 -6.2466764795620975,106.9030592137999 -6.2572561867229695,106.9133845599307 -6.262008538409347,106.95252335387602 -6.2596196127164205,106.96694290954008 -6.258254507414847,106.9573298724307 -6.241872965808085,106.95389664489164 -6.226514805263562,106.95561325866117 -6.209108347048627,106.9466868670596 -6.195455820296004,106.94256699401275 -6.137428650997094,106.92677414733305 -6.1094368121346605,106.92334091979399 -6.1043161952327125,106.89209854918852 -6.1043161952327125,106.86703598815336 -6.11524011873955,106.84472000914946 -6.124457005651777,106.8251506121768 -6.127870627111122,106.81279099303616 -6.125481094381513,106.791504982294 -6.128553348783186,106.78358289544055 -6.133699250072027))

Please let me know if you need more information.