Open vvoovv opened 11 months ago
(2)
A PML style is set for the instance of the class Street
using the function getStyle
supplied to the class StreetGenerator
. The categories of street sections and the number of roadways will be used to assign a PML style to an instance of the class Street
.
(3)
A PML style should contain a style block street
with the @setup
directive where the default attributes are set:
@setup
street {
numLanes: random_weighted( (2, 70), (4, 30) );
numLanesOneway: random_weighted( (1, 75), (2, 25) );
}
Those style blocks with the @setup
directive are evaluated immediately after assigning the PML style. The evaluated attributes numLanes
and numLanesOneway
and other, if provided, will be used if the number of lanes is not given in the OSM data for a street section.
(4)
Perform the initialization like in the current method createWaySections()
: setting the number of lanes, calculating widths, etc,
(5) Crosswalks should be extracted from the OSM data.
An OSM node representing a crosswalk is tagged with crossing=*
. I suggest using the attribute crosswalkNodeIndices
in the class Section
to store a Python list of node indices of the cropped centerline where a sidewalk is located.
An OSM node with a crosswalk may be in the cropped part. In that case case the index of the node with the crosswalk will be 0 or N-1, where N is the number of nodes in the cropped centerline.
(1) Create instances of the class
Section
(currentlyStreetSection
). The attributesstart
andend
are set to either a neighborSection
or an intersection or None (in the case of a dead-end).
Intersection areas do not yet exist at this stage. Perhaps, the positions of the intersection nodes (currently of mathutils Vector
class) could be used as keys to a container, that will later be filled by instances of theIntersectionArea
class that belong to these nodes. Later in the process, the start
and end
attributes will need to be adjusted, when intersections are merged or clustered.
Besides neighbor sections, intersections and dead-ends, instances of a TransitionSymLane
class or a TransitionSideLane
class should also be considered as contents of the start
and end
attributes. But there we have the same problem as above, they do not exist yet at this time.
Street sections are grouped into roadways. A street may have one, two or more roadways. If a street contains two or more roadways, then they are grouped into a cluster.
I am not sure if I understand this correctly. Does the Roadway
class group also include streets that are separated by instances of a TransitionSymLane
class or a TransitionSideLane
class, as shown here, or is Roadway
somehow a replacement for what we had with the WayCluster
class? Note that clusters do not yet exist at this stage.
The class
Roadway
should have an attributestart
. It is the reference to the first street section (an instance of the classSection
) in the roadway. The other street sections in the roadway can be accessed with the related linked list (the attributesstart
andend
of the classSection
).
This will work fine for linear cases, like those with the TransitionSymLane
class or a TransitionSideLane
class, as described above. But it will not work for clusters, because multiple way-sections may start from the same (clustered) intersection. Then, the start
attribute will have to be a list.
The evaluated attributes numLanes and numLanesOneway and other, if provided, will be used if the number of lanes is not given in the OSM data for a street section.
I still do not understand this idea. The only case I know of where the number of lanes is not specified in OSM is when there is no lanes
tag. Then, as far as I know, OSM assumes one lane for one-way streets and two lanes for the others. Would it make sense to change this using random numbers from the PML attributes?
EDITED:
It seems that I am wrong. We even defined a default number of lanes in our default way properties wayCategoryProps
in _wayproperties.py. I don't know to what extent this was justified. However, maybe the question is whether this table should be moved to PML eventually, as these numbers may have some locale aspect.
(5) Crosswalks should be extracted from the OSM data. An OSM node representing a crosswalk is tagged with
crossing=*
. I suggest using the attributecrosswalkNodeIndices
in the classSection
to store a Python list of node indices of the cropped centerline where a sidewalk is located.
This is now new to me. I searched for OSM objects tagged as crossing=*
using overpass turbo and got something like this:
The result seem to be footways. What do you mean by "node indices of the cropped centerline where a sidewalk is located"? Are these the nodes of the trimmed centerline, between them a crossing footway intersects the centerline? Or are you talking about objects that are marked as sidewalk
?
Intersection areas do not yet exist at this stage.
How about using an empty Intersection
class? It can be later filled with values.
Besides neighbor sections, intersections and dead-ends, instances of a
TransitionSymLane
class or aTransitionSideLane
class should also be considered as contents of thestart
andend
attributes. But there we have the same problem as above, they do not exist yet at this time.
Linked lists allow inserting and removing items easily. So a TransitionSymLane
or a TransitionSideLane
can be inserted later once the numbers of lanes are set and the calculations are performed. Similarly, a future Footprint
class or a PtStop
class (for a public transport stop) can be inserted into a linked list that forms a Roadway
class. I will write about those classes later.
I am not sure if I understand this correctly. Does the
Roadway
class group also include streets that are separated by instances of aTransitionSymLane
class or aTransitionSideLane
class, as shown here, or isRoadway
somehow a replacement for what we had with theWayCluster
class? Note that clusters do not yet exist at this stage.
A class Roadway
holds a reference to a linked list that is made of instances of the classes Section
, TransitionSideLane
, TransitionSymLane
, Footway
, PtStop
, etc. In the majority of cases it contains just a single instance of Section
.
The class Street
can be considered as a replacement of the class WayCluster
. However in the majority of cases it contains just a single instance of the class Roadway
.
It would be highly desirable to do clustering before assigning a PML style to an instance of the class Street
, since a double-roadway street looks differently than a single roadway street.
This will work fine for linear cases, like those with the
TransitionSymLane
class or aTransitionSideLane
class, as described above. But it will not work for clusters, because multiple way-sections may start from the same (clustered) intersection. Then, thestart
attribute will have to be a list.
Do you mean something like on the image below? The intersections at the start and at the end of an instance of the class Street
are shown with the blue color.
However, maybe the question is whether this table should be moved to PML eventually, as these numbers may have some locale aspect.
Yes, that table should be moved to PML.
Using the function random_weighted
to set the number of lanes and other attributes does make sense. All street categories have the most probable value of the number of lanes. But there are always exceptions. Other values of the number of lanes can also happen with a smaller probability.
This is now new to me. I searched for OSM objects tagged as
crossing=*
using overpass turbo and got something like this:
The tag crossing=*
is applied only to nodes.
The result seem to be footways. What do you mean by "node indices of the cropped centerline where a sidewalk is located"? Are these the nodes of the trimmed centerline, between them a crossing footway intersects the centerline? Or are you talking about objects that are marked as
sidewalk
?
Let's consider the following intersection:
Suppose that the OSM way on the right starts in the center of the intersection. A node with the sidewalk marked with the red color has the index 2
in the OSM way. After generating the intersection, nodes with the indices 0 and 1 will be cropped. A new node with the index 0 will placed at the border with the the intersection. The node with the crosswalk will have the index 1 after cropping.
I suggest introducing a new data element Bundle
for complex cases like on the image below:
An instance of the class Street is always composed of a chain of items represented by a chained list. For the above example:
Section
| SplitMerge
| Bundle
An instance of the class Bundle
defines parallel chains or threads or items. I don't know yet what is the proper name for that.
In the example above a bundle would have: Section
in the lower roadway and another Section
in the upper roadway.
Consider a more complex example:
Abbreviations used in the image:
(S) - Section
(C) - Crosswalk
(PT) - PtStop
(SM) - SplitMerge
The chained list for this case:
Section
| Crosswalk
| Section
| PtStop
| Section
| SplitMerge
| Bundle
The chained list for the lower roadway of the Bundle
:
Section
| Crosswalk
| Section
The chained list for the upper roadway of the Bundle
:
Section
| Crosswalk
| Section
| PtStop
| Section
A Bundle
can have another Bundle
in its roadway.
Note that the class Roadway
is not used anywhere in the examples. At the moment I am not sure if it is needed at all.
The tag
crossing=*
is applied only to nodes.
You are right, I did a mismatch in my overpass turbo query. We will need a new method in the WayManager
class to query for these crossing nodes, similar to getAllVehicleWays()
.
I suggest using the attribute
crosswalkNodeIndices
in the classSection
to store a Python list of node indices of the cropped centerline where a sidewalk is located. An OSM node with a crosswalk may be in the cropped part. In that case the index of the node with the crosswalk will be 0 or N-1, where N is the number of nodes in the cropped centerline.
It will be easy to derive this number from the trim parameter of the way-section's polyline.
How about using an empty Intersection class? It can be later filled with values.
Yes, this will be the solution.
Linked lists allow inserting and removing items easily. So a TransitionSymLane or a TransitionSideLane can be inserted later once the numbers of lanes are set and the calculations are performed. A class
Roadway
holds a reference to a linked list that is made of instances of the classesSection
,TransitionSideLane
,TransitionSymLane
,Footway
,PtStop
, etc.
I assume you mean a linear, doubly linked list. But that requires that the position of all these objects (TransitionSymLane
, TransitionSideLane
, Footprint
or a PtStop
) has to be detected before this list is constructed. Otherwise, we risk, that a Section
has to be split by one of these objects later:
| -------- Section --------| => | ---- Section ----| --PtStop--| ---- Section ----|
It would be highly desirable to do clustering before assigning a PML style to an instance of the class
Street
, since a double-roadway street looks differently than a single roadway street.
In principle, the complete 2D topology has to be known before PML styles get assigned. This is possible, I think, but it is a major redesign.
Do you mean something like on the image below? The intersections at the
start
and at theend
of an instance of the classStreet
are shown with the blue color.
Yes. You wrote:
The class Roadway should have an attribute start. It is the reference to the first street section (an instance of the class Section) in the roadway. The other street sections in the roadway can be accessed with the related linked list (the attributes start and end of the class Section).
On the right side of the drawing, there are two starts
.
I suggest introducing a new data element
Bundle
for complex cases like on the image below:
I like this idea, and I also think the term Bundle
fits the underlying structure well.
What I still don't really like is the special importance of an intersection. If I put an additional one to one of the arms of the bundle, a situation that occurs frequently, the structure gets split somehow, it is no more linear. While the Crosswalk
in your illustration appears on both parallel ways of the bundle, an intersection can't do that:
However, I am afraid I do not have a reasonable suggestion as to how this could be improved.
I assume you mean a linear, doubly linked list.
Yes.
Otherwise, we risk, that a
Section
has to be split by one of these objects later: | -------- Section --------| => | ---- Section ----| --PtStop--| ---- Section ----|
I don't consider splitting of sections as a risk. I consider splitting as an integral part of the workflow, since it's required to split the related Section
to insert an instance of Crosswalk
or PtStop
. The calculations can be delegated to the Geometry Nodes, but then the trim lengths are needed as the input parameters for the GN-setup.
I forgot to describe the case of the lower arm of the bundle. Here we would have:
Section
| PartialIntersection
| Section
I don't consider splitting of sections as a risk. I consider splitting as an integral part of the workflow ...
I am somewhat reluctant to use this seemingly simple solution of mapping all routes with linked lists. Let me try to explain my reasons.
The simple splitting of sections (list nodes) within a doubly-linked list is quite simple and well known. A problem arises when it is necessary to find all these sections at once. This is the case when they have to be inserted into a spatial index (for performance reasons). Then you have to search all of them along many linked lists, insert them into the index, and somehow provide a reference to find them backwards, when some of them are given as a result of an index operation (for example, find all neighbors of one of them). If any changes have to be made due to such an operation, the change is not only in the linked list, but also in the reference index. Of course this is possible, but it is quite complicated and prone to errors.
There are several tasks in the whole process, for instance building clusters or merging intersecting areas, where such situations occur. As I said, I had some concerns and therefore did not choose such approaches in my previous solution. But let's give it a try.
As I said, I had some concerns and therefore did not choose such approaches in my previous solution. But let's give it a try.
What are the alternatives? Perhaps there is a way to combine two approaches.
What are the alternatives? Perhaps there is a way to combine two approaches.
You have studied what it takes to use PML in a meaningful way. This way, I get very concrete requirements for the processes in StreetGenerator, and we establish a more detailed cooperation. Even though it means resetting and redesigning much of the development that has already been done, I like this situation. So let us try to find a solution.
Many of the previous ideas can be reused, perhaps in a slightly different form. I am wondering: Should we start a new branch so that the previous code is preserved even if it is no longer used? I already stored a lot of functions in the code that do not currently have any use.
I created the tag dev_before_street_pml
pointing to the current version of the branch streets_for_gn
. That's another way to preserve the code. Legacy functions can be kept in a dedicated Python module.
I like this idea, and I also think the term Bundle fits the underlying structure well.
I would like to take a closer look at the "bundle" concept. When we used clusters, these were constructed more or less together as cluster-way and cluster-intersection. Here are two examples of such cluster intersections, on the left the simple one (East of Karl-Marx-Allee scene) and on the right a more complicated one with four way section ends, two of which go underground (Moscow scene).
Intersection areas can only be calculated if the width of all way-sections is known, which is not yet the case when getStyle
is called for PML processing. At this point, only for the first, simpler example (left image), it is known that every two paths with their endpoints belong to a Bundle
.
My suggestion now is that I try to find the intersections that belong to these endpoints and define their center of gravity as the provisional node of a still incomplete intersection (red in the right image). Each of its connectors could then be a list of instances of the Section
class, holding the way-section, that start at this (bundle) intersection.
But what to do with the sections marked by green lines? When we were working with clusters, in most cases they had to be deleted at the time when the area was constructed. But I'm not sure whether it would be safe to remove them before the getStyle
call. On the other hand, it would be complicated to hold them using the single endpoint intersections in addition to the temporary clustered intersection. I'll have to think about that.
What if the largest possible roadway width is used to detect a cluster of roadways?
I am currently investigating structures that can be used locally in StreetGenerator
, with which I can then create the desired class instances ready for a call to getStyle
. In the meanwhile, a few new questions have arisen.
The first ones arise from the question we have already begun to discuss in issue #66. We need to define directions for the linear structures proposed in this thread, they should have a source (src) vertex and a destination (dst) vertex. Instances of the class Section
should use the definition given by OSM: Forward is in the direction of the drawing (the order of the nodes) and backward is in the opposite direction. By the way: We should probably not forget the driving_side
tag.
The question is, how shall we define the directions of the higher-level structures (Roadway
, Bundle
)? For Roadway
, we could use the direction of the internal Section
instances. But the same would not work always for a Bundle
(draw direction in red):
If we were to use the x- and y-coordinate rules, the start coordinates of the Roadway
instances could sometimes be on opposite sides of the bundle.
At the call to getStyle
, do the lane attributes of a Section
instance already need to be computed?
self.isOneWay = False # True if one-way road.
self.totalLanes = None # Total number of lanes, includes bothLanes
self.forwardLanes = None # Number of forward lanes
self.backwardLanes = None # Number of backward lanes
self.bothLanes = None # Number of lanes that allow a turn available in both directions (tag lanes:both_ways)
I already often flirted with using the library networkx for various network tasks in the blosm addon. But I didn't know how to install the library inside Blender, since pip install is not possible. But now, I found an article here, showing how easy it can be. In principle, it is sufficient to import a specific folder with pure Python code, similar as we did with ANTLR4 for PML, for example. I tested it and it works fine.
So I decided to base the refactoring of the StreetGenerator
on this library. Perhaps it would make sense to rewrite some older code later, if it is based on graphs and networks.
At the call to
getStyle
, do the lane attributes of aSection
instance already need to be computed?
It's not required.
I already often flirted with using the library networkx
I see the packages scipy
and pandas
in the dependency list. Do the modules of networkx
which you used in your tests, import those packages? Can networkx
be just copied to blosm folder and used as-is?
Installing external packages for Blender's Python can be very tricky taking into account a broad user base of the addon.
The question is, how shall we define the directions of the higher-level structures (
Roadway
,Bundle
)?
At the moment I can't propose for bundles anything else besides the XY-coordinates rule. The details of the calculation can be hidden in a method getDirection
or similar. The practice will show which method to determine the direction will be the best.
I see the packages scipy and pandas in the dependency list
In my (small and short) tests, using a copy of NetworkX in a local folder worked fine without any problems. I wasn't even aware of these dependencies (so thanks for your check). Somewhere in the NetworkX documentation, I found the text:
There are no dependencies for NetworkX’s core functionality, such as the data structures (Graph
, DiGraph
, etc.) and common algorithms, but some functionality, e.g. functions found in the networkx.linalg
package, are only available if these additional libraries are installed.
I will now spend some time investigating the possibility of creating a core version of this library using only pure Python. Once I see such a possibility, I will see if it is complex enough to solve my problems. If so, I could save a lot of time.
Have you compared the performance of NetworkX with your code?
Have you compared the performance of NetworkX with your code?
I do not have code of my own yet. What I need is a directed multigraph structure, that can store objects (Intersection
, TransitionSymLane
, TransitionSideLane
, Footprint
, PtStop
, ...) as nodes and objects of Section
as edges. My existing network code does not provide this. NetworkX would provide that "for free", including the base for a "split section" algorithm.
But maybe I'll take some inspiration from the NetworkX code for my own code. The first experiments to create a core version were not very promising.
I created the tag
dev_before_street_pml
pointing to the current version of the branchstreets_for_gn
. That's another way to preserve the code. Legacy functions can be kept in a dedicated Python module.
The command git pull origin --tags
can be used to get the tags from a remote repository.
An instance of the class
Bundle
defines parallel chains or threads or items.
I suggest naming them items
. The items are ordered from left to right along the direction of a bundle.
But maybe I'll take some inspiration from the NetworkX code for my own code. The first experiments to create a core version were not very promising.
Finally, I was able to create a version of NetworkX that excludes all unwanted dependencies and works fine for my purposes. I renamed it to _blosmnetworkx and added it to our lib folder. The new code, which already constructs a way-map with empty intersections, is committed. All the classes required to hold the new objects are collected in a new folder way/waymap. I will fill them with life, one by oner.
So far, we have defined several types of objects, which I have called nodes and which are collected in the way/waymap/nodes folder. To build a map, all these objects have a location
attribute, even though they may actually be areas. location
is the search-key to finding them in the way-map:
Intersection, PartialIntersection, SideLane, SymLane, Crosswalk, PtStop, DeadEnd
Some of these nodes may have multiple connections, so we need to define something similar to the connectors, that we had before. Then we need three line objects, each with a source attribute src
and a destination attribute dst
, which are the locations of nodes and together are used as keys in the way-map:
Section, Roadway, Bundle
In most cases, a Roadway
will contain only a single section, but it can also contain a sequence of sections. . We defined that the Section
class has two attributes start
and end
, which hold references to the preceding and following objects. Note that these are not the same as the location src
and dst
attributes. Since these form a doubly linked linear list, I would prefer to call these attributes pred
, for predecessor, and succ
, for successor.
All nodes, except DeadEnd
, usually split their section. The objects Intersection
, PartialIntersection
, SymLane
and Crosswalk
become an area, so that their connecting sections must be trimmed. SideLane
is just a tool to render turning lanes. I do not know yet if PtStop
will split its section.
It is still unclear to me where a Roadway
sequence ends when more than one section is used. Is it only at Intersection
and PartialIntersection
, while the other nodes are included in the Roadway
? Let us discuss some of my questions using the following example:
Intersections and partial intersections are blue. I have replaced your SplitMerge
object in the middle with an Intersection
object, as it was done before for clusters. To the left of this object, my question is now: Should the crosswalk or the bus-stop or both be included in a Roadway
object? On the right, can a Bundle
be constructed somehow (in the old implementation, without crosswalk and bus-stops, this was a cluster). Where does the Crosswalk
belong to?
Finally, I was able to create a version of NetworkX that excludes all unwanted dependencies and works fine for my purposes.
It would be good to describe it briefly how to get this version.
a way-map
I suggesting adding the definition of a way-map to our section Definitions.
It would be good to describe it briefly how to get this version.
The version of _blosmnetworkx in the lib folder of the blosm addon is based on the latest release 3.2.1 of NetworkX downloaded from its GitHub repository on 12/16/2023. Only the code in its folder networkx is used.
Blender does not support the scipy and pandas packages, which are part of the NetworkX requirements. Therefore, we have reduced our version (_blosmnetworkx) by removing all files in it, that use functions from these packages or derivatives of methods that use them.
In detail, we did:
I suggesting adding the definition of a way-map to our section Definitions.
The way-map, as I intend to use it, does not fit into these (by the way very old) definitions. It is just a tool of mine to keep all objects in a single structure. It has two main purposes. First, it should be a factory for any linked lists you want to have. Second, it should allow me to perform operations, such as splitting ways, without needing to find the same object in multiple structures. It should be a solution to the problem mentioned here. At present, its functionality is still rather unclear and experimental.
What about the new definitions Intersection, PartialIntersection, SideLane, SymLane, Crosswalk, PtStop, DeadEnd, Section, Roadway, Bundle
?
I suggest moving modules from way/waymap/nodes and way/waymap/section to way/items like it's done for buildings.
What about the new definitions
Intersection, PartialIntersection, SideLane, SymLane, Crosswalk, PtStop, DeadEnd, Section, Roadway, Bundle
?
I like them. At the moment I am not sure if the item Roadway
will be needed at all.
I suggest moving modules from way/waymap/nodes and way/waymap/section to way/items like it's done for buildings.
Done.
If you ever get some time: I could use a manager to find the nodes for crosswalks and public transport stops from the OSM data. I think this can't be done using theWayManager
, or am I wrong?
Some of these nodes may have multiple connections, so we need to define something similar to the connectors, that we had before. Then we need three line objects, each with a source attribute
src
and a destination attributedst
, which are the locations of nodes and together are used as keys in the way-map:Section, Roadway, Bundle
The existing class Intersection
can be used for now. I don't understand what is meant under three line objects.
Note that these are not the same as the location
src
anddst
attributes.
How will the attributes src
and dst
be used?
I would prefer to call these attributes
pred
, for predecessor, andsucc
, for successor.
How about calling them prev
and next
?
I do not know yet if
PtStop
will split its section.
A PtStop
can split the adjacent sections if it has a special marking on the roadway and/or a bus bay as shown at https://github.com/prochitecture/blosm/issues/76#issue-2042341403
It is still unclear to me where a
Roadway
sequence ends when more than one section is used. Is it only atIntersection
andPartialIntersection
A Roadway
can end at Intersection
. It can't end at PartialIntersection
.
I have replaced your
SplitMerge
object in the middle with anIntersection
object, as it was done before for clusters.
I thought SplitMerge
and Intersection
are different. A Street
can't end at a SplitMerge
. A Roadway
can be split into a number of items at a SplitMerge
or several items of a Bundle
can be merged into a single Roadway
at the SplitMerge
.
Should the crosswalk or the bus-stop or both be included in a
Roadway
object?
Yes.
On the right, can a
Bundle
be constructed somehow (in the old implementation, without crosswalk and bus-stops, this was a cluster). Where does theCrosswalk
belong to?
A Bundle
can be considered as an upgraded version of a Cluster
. Without crosswalks and pt-stops we would have:
Roadway
: Section
Roadway
: Section
| SplitMerge
| Section
The Crosswalk
belongs to both roadways.
The existing class Intersection can be used for now. I don't understand what is meant under three line objects.
I had some trouble with the language. Unlike nodes, which are local objects, Section
, Roadway
, and Bundle
have a length and are similar to a line. So I called them line objects. Linear did not seem correct to me, as it somehow means straight to my understanding. I couldn't find any better term.
How will the attributes
src
anddst
be used?
They will be instances of mathutils.Vector
and will only be used as keys in the way-map structure, that inherits from MultiDiGraph
, a class of the blosm_networkx.
How about calling them
prev
andnext
?
I wanted to avoid that, because next
is a Python keyword. Note that in contrast to src
and dst
, these are references to objects.
A
PtStop
can split the adjacent sections if it has a special marking on the roadway and/or a bus bay as shown at https://github.com/prochitecture/blosm/issues/76#issue-2042341403
You say "can split", and, in https://github.com/prochitecture/blosm/issues/76#issuecomment-1856469792, "The related Section
may be split ...", both ambiguous, therefore my question. What construction with Section
should it be, if not split? What are the rules for when to split and when not to split?
A
Roadway
can end atIntersection
. It can't end atPartialIntersection
.
I will need a recipe on how a Roadway (and a Bundle
) is constructed.
I thought SplitMerge and Intersection are different. A Street can't end at a SplitMerge. A Roadway can be split into a number of items at a SplitMerge or several items of a Bundle can be merged into a single Roadway at the SplitMerge.
We never had a SpliMerge
until now, this term is new. I can't imagine a situation, where a Bundle
gets merged into a single Roadway
. What we had until now was a SymLane
, which connected two way-sections with different width, using an area (-> split), or an IntersectionCluster
, which was the intersection at the end of a cluster. Something like this:
So I called them line objects.
A pt-stop is also a line object, it may have a noticeable length. It's another reason why I proposed to move all of them to the directory items
.
I would prefer to call these attributes
pred
, for predecessor, andsucc
, for successor.
Ok, let's use the names pred
and succ
.
What construction with
Section
should it be, if not split? What are the rules for when to split and when not to split?
A PtStop
splits its section if there is a special marking on the roadway and/or a bus bay. There is no need to split the section if a pt-stop is only marked with a pole on the sidewalk. That will be defined in the PML style.
I will need a recipe on how a Roadway (and a
Bundle
) is constructed.
The construction of Roadways can skipped for now. I suggest considering ambiguous cases for the constructions of Bundles.
We never had a
SpliMerge
until now, this term is new.
An example of a possible class SplitMerge
can be found at _berlin_karl_marxallee.osm on Strasse der Pariser Kommune. The image below was rotated.
If you ever get some time: I could use a manager to find the nodes for crosswalks and public transport stops from the OSM data. I think this can't be done using the
WayManager
, or am I wrong?
The code to detect and process crosswalks and pt-stops must be developed. I suggesting discussing that in #73 and #76.
An example of a possible class SpliMerge can be found at berlin_karl_marx_allee.osm on Strasse der Pariser Kommune. The image below was rotated.
OK, we can introduce the additional class SplitMerge
. The problem for the example at the Strasse der Pariser Kommune is the distance between the end of the Bundle
and the position of the intersection of the OSM-ways, here shown as a result of the old implementation using clusters:
The cluster (green area) ends where the ways are no more parallel (red dots). From there, the intersection of the OSM-ways (yellow dot) is more than 30 m away. It is now a matter of heuristics whether such a long distance is accepted as a single area connected to the cluster or not.
The SplitMerge
class will have an area polygon and three connector-like records as attributes, just like an Intersection
. It could be defined as a special intersection, that merges two one-way Sectionsof opposite directions
within a Bundle
into a two-way Section
. Some kind of maximum size for such a structure will have to be defined.
Below is the example of a pure N-to-1 merge at Tijuana border crossing. There is also a pure 1-to-N split next to this spot.
Nevertheless, the class still can be named as SplitMerge
.
(1) Create instances of the class
Section
(currentlyStreetSection
). The attributesstart
andend
are set to either a neighborSection
or an intersection or None (in the case of a dead-end).Street sections are grouped into roadways. A street may have one, two or more roadways. If a street contains two or more roadways, then they are grouped into a cluster.
The class
Street
should have an attributeroadways
. It's a Python tuple with a single element in the case of a single roadway and a Python list in the case of two or more roadways.The class
Roadway
should have an attributestart
. It is the reference to the first street section (an instance of the classSection
) in the roadway. The other street sections in the roadway can be accessed with the related linked list (the attributesstart
andend
of the classSection
).