Trying to creating roads from a 2D texture into a 3D map using RoadArchitect

I need help with a complex task I’m trying to creating roads using RoadArchitect: https://github.com/FritzsHero/RoadArchitect/tree/RewrittenAPI I’m trying to detect all roads from a texture. I have created a model class to store every detected road using a little bit of recursion:

    [Serializable]     public class RoadNode : IPathNode     {         //[JsonConverter(typeof(RoadNodeConverter))]         public ConcurrentBag<int> Connections { get; set; } // TODO: IPathNode<T> + RoadNode : IPathNode<RoadNode> + Connections (ConcurrentBag<RoadNode>), but can't be serialized due to StackOverflow and OutOfMemory exceptions          public Point Position { get; set; }         public bool Invalid { get; set; }         public int Thickness { get; set; }         public ConcurrentBag<int> ParentNodes { get; set; }          public RoadNode()         {             //Connections = new List<RoadNode>();         }          public RoadNode(Point position, int thickness)         //: this()         {             Position = position;             Thickness = thickness;         }          public RoadNode(Point position, bool invalid, int thickness)         //: this()         {             Position = position;             Invalid = invalid;             Thickness = thickness;         }          public RoadNode(int x, int y, int thickness)             : this(new Point(x, y), thickness)         {         }          public void SetThickness(int thickness)         {             // TODO: Call this when needed and thickness == -1             Thickness = thickness;         }          public int GetKey()         {             return F.P(Position.x, Position.y, mapWidth, mapHeight);         }     } 
    public interface IPathNode     {         ConcurrentBag<int> Connections { get; }         Point Position { get; }         bool Invalid { get; }     } 

At every loaded chunk (I’m using SebLeague tutorial to create the chunks), I get all the road points for this chunk. Then, I try to iterare them. But I have problems interpreting the results.

I have part of the task done:

        public static IEnumerable<Road> CreateRoad(this IEnumerable<Point> points, StringBuilder builder)         {             if (points.IsNullOrEmpty())             {                 builder?.AppendLine($  "\tskipped...");                 yield break; // This chunk doesn't contain any road. Exiting.             }              //var dict = points.Select(p => new {Index = p.GetKey(), Point = p}).ToDictionary(x => x.Index, x => x.Point);             //var builder = new StringBuilder();             var roads = GetRoads(points, builder);             foreach (var list in roads)             {                 if (list.IsNullOrEmpty()) continue;                 //var first = road.First();                 //var backIndex = ((Point)CityGenerator.SConv.GetRealPositionOnMap(first)).GetKey();                  var road = CreateIndependantRoad(list);                 builder?.AppendLine($  "\t... finished road ({road.name}) with {list.Count} nodes.");                 yield return road;             }             //Debug.Log(builder?.ToString());         }          private static IEnumerable<List<Vector3>> GetRoads(IEnumerable<Point> points, StringBuilder builder)         {             var model = RoadGenerator.RoadModel;              var queue = new Queue<Point>(points);             int i = 0;              builder?.AppendLine($  "\tcount: {queue.Count}");              var dictionary = new Dictionary<int, List<Vector3>>();              while (queue.Count > 0)             {                 var list = new List<Vector3>();                  var pt = queue.Dequeue();                 var itemIndex = pt.GetKey();                 dictionary.Add(itemIndex, list);                  var node = model.SimplifiedRoadNodes[itemIndex];                  builder?.AppendLine($  "\troad iteration: {i}");                  //var conn = node.Connections;                 var nodes = GetRoadNodes(node, ptVal =>                 {                     if (ptVal.HasValue) queue = new Queue<Point>(queue.Remove(ptVal.Value));                     return queue;                 },                     parentNodeIndex => { return dictionary[parentNodeIndex]; },                     builder);                  foreach (var point in nodes)                     list.Add(CityGenerator.SConv.GetRealPositionOnMap((Vector2)point).GetHeightForPoint());                  yield return list;                 ++i;             }         }          private static IEnumerable<Point> GetRoadNodes(RoadNode node, Func<Point?, Queue<Point>> queueFunc, Func<int, List<Vector3>> parentFunc, StringBuilder builder, int level = -1)         {             if (queueFunc == null) throw new ArgumentNullException(nameof(queueFunc));             if (parentFunc == null) throw new ArgumentNullException(nameof(parentFunc));              var conn = node.Connections;             if (conn.IsNullOrEmpty())             {                 yield return node.Position;                 yield break;             }             if (queueFunc(null).Count == 0) yield break;              ++level;             builder?.AppendLine($  "{new string('\t', 2)}level: {level} -> {queueFunc(null).Count} items");              //if (conn.Count == 1)             //{             //    var firstNode = conn.First().GetNode();             //    ////var firstPoint = conn.First().GetPoint();              //    var list = parentFunc(firstNode.ParentNodes.First()); // TODO: parent nodes should be one...             //    list.Add(CityGenerator.SConv.GetRealPositionOnMap((Vector2)conn.First().GetPoint()).GetHeightForPoint());             //}             //else             {                 foreach (var item in conn)                 {                     var pt = item.GetPoint();                     if (!queueFunc(null).Contains(pt)) yield break;                     yield return pt;                     if (queueFunc(pt).Count == 0) yield break;                      var subnode = pt.GetKey().GetNode();                     var pts = GetRoadNodes(subnode, queueFunc, parentFunc, builder, level);                     foreach (var point in pts)                         yield return point;                 }             }         } 

You can see here the StringBuilder results: https://pastebin.com/1tW4V4BC

But as you can see I have problems with roads. Some roads only have one node, other roads only have 2 nodes…

I’m thinking that the current implementation I did isn’t right at all, because instead of grouping all nodes into one major road I’m splitting them into road chunks without sense.

By this reason I created this topic, in order to clarify myself because I’m not sure about what I’m doing and which way should I take.

Visualisation of the state of roads on a map

I am designing a website with different kind of roads for bikers. I am looking for a way to show on a Google maps overlay what the state of the roads is. What is the best practice of this?

There are a few states, although with different names, but in its simplest form:

  1. High Quality roads
  2. Medium Quality Roads
  3. Low Quality roads
  4. under construction/usable soon
  5. under construction: being repaired

As you can see on the image below there are only 2 codes right now and different qualities can be shown on 1 road.

Screen capture

I appreciate every input!

Overview (map) of Russian long-distance river regular passenger ships in regions too remote for roads or railways

It appears many of the big Russian rivers have passenger ships going along the river, in areas where roads and railways do not reach:

  • PassazhirRechTrans on the Yenisey
  • Ust-Shugor to Vuktyl at the Pechora, mentioned at the English language Yugyd-Va page, maybe also from the Pechora town?
  • Lena River north from Yakutsk, and apparently from Ust-Kut as well, therefore connecting to the Trans-Siberian railway?
  • Ob River between Омск (Omsk) and Салехард (Salekhard), on infotransport, severflot and Openstreetmap
  • Likely on other rivers as well, for example, severflot operates on the Ob, Irtysh, Konda, Kazim, Severnaya Sosva, Lyapin, Nadym, and Vakh rivers.

It seems such boats could be a suitable way to connect from the Trans-Siberian railway to (even) more remote locations (such as the vicinity of Lake Vivi), where roads and railways do not reach. However, I find it difficult to find information about such boats, routes, schedules, etc.. Where can I find an overview, preferably a map, of long-distance boats in Russia? By long-distance boats I mean boats that run along the river for at least some dozens of kilometres, but preferably for several days, as opposed to ferries that simply cross the river from shore to shore.

Note that I’m looking for regular passenger ships, not special tourist cruises. Specifically, I’m looking for areas where travel by river is the only way of transportation, such as in the examples I’ve shown; there are no roads or railways in these areas.

I don’t think this map from Wikimedia Commons shows actual passenger ship routes, just old used routes:

something like this I'm looking for

So, a map like this but with actually trafficated routes would be nice to see!