<p>Let me try to make one more run at breaking the log-jam.</p>
<p>The impasse with <a class="user-mention" data-hovercard-type="user" data-hovercard-url="/hovercards?user_id=1447941" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/lonvia">@lonvia</a> appears to be that she is concerned with the performance implications of a run-time JOIN during rendering.  I begin to see how sufficiently clever preprocessing when updating the tables could avoid such a beast for the specific case of route relations. I still have questions that would influence the design of such a thing.  I'm hoping that I can get answers to them that would allow me to move forward. Otherwise, the requirement of "come up with a fully fleshed proposal for examination" is nearly tantamount to "go away," since that is so very inefficient a method for discovering what hidden requirements a proposal must satisfy.</p>
<p>I do get the idea of adding a 'shields' column to the database, as <a class="user-mention" data-hovercard-type="user" data-hovercard-url="/hovercards?user_id=1447941" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/lonvia">@lonvia</a> suggested <a href="https://github.com/openstreetmap/osm2pgsql/issues/230#issuecomment-426570704" data-hovercard-type="issue" data-hovercard-url="/openstreetmap/osm2pgsql/issues/230/hovercard">earlier</a>.  In the case of rendering concurrent routes, this column would need to comprise a delimited list of alternating values of <code>network</code> and <code>ref</code> from the route relation. (Here, I'm assuming that the type of the column must be a simple type such as INTEGER or TEXT. Obviously, if ARRAYs can be supported here, they'd be preferred!)</p>
<ul>
<li>Q1: Is the presence of such a 'synthetic' attribute acceptable? *</li>
<li>Q1a: Are ARRAYs feasible here? *</li>
</ul>
<p>Obviously, 'network' and 'ref' by themselves are not enough to do attractive rendering of shaped markers. I imagine that there will be additional calculation at render time to retrieve a marker and use either a <code>ShieldSymbolizer</code> or a <code>PointSymbolizer</code> to do the actual rendering (under control of a <code>GroupSymbolizer</code> to handle clusters).  This may involve an additional lookup of some sort to retrieve an appropriate graphical item. The lookup could conceivably be a JOIN operation, but in this case it would be a JOIN in which the outer table contains only items that we are already committed to rendering. This JOIN could be avoided by making the rendering decision at the time that the tables are updated, but such a design strikes me as a premature optimization and as a breaking of the division of responsibilities between database and renderer.</p>
<ul>
<li>Q2: Is the presence of a lookup of a graphical element a showstopper? (Otherwise, I can move forward with the assumption that the 'network/ref' pair is what will be used.) *</li>
<li>Q2a: In the alternative, what is an appropriate way, when setting up this sort of system, to communicate the rendering rules to 'osm2pgsql' so that graphical elements can be retrieved without further database activity? *</li>
</ul>
<p>My experience suggests that rendering of route markers can be made much more attractive and readable by coalescing ways that belong to the same routes. A route may be fragmented into a great many short ways, to represent bridges, changes in speed limits, changes in number or purpose of traffic lanes, presence or absence of cycleways or pavements, etc. Considering these short ways in isolation makes it extremely difficult to place markers at approximately equal intervals. By the same token, coalescing ways that belong to a single route means that there will be multiple ways that follow the same nodes, with no indication that they are concurrent - which was the original problem to be solved.</p>
<p>The correct coalescence for this particular case is to merge ways that belong to the same <em>set</em> of route relations, rather than all ways for a given route relation.  This is <em>not</em> consistent with how routes are stored in the <code>line</code> and <code>roads</code> tables today, and I do <em>not</em> propose to change that, so as not to have impact on existing code that uses those tables. There are two major alternatives:</p>
<p>(1) Simply store the <code>shields</code> information with the individual ways. At render time, once the ways have been retrieved, run ST_LineMerge on the result set (grouping by <code>shields</code> to coalesce the lines before returning them to the renderer. This method adds some computation on the database side, but is operating only on data that are known to participate in the rendering, and are already in memory buffers in PostgreSQL. Data outside the bounding box will not be considered in the merge.</p>
<p>(2) Pre-merge the ways that correspond to each set of routes. These merged ways would need to be stored in a separate table analogous to <code>roads</code>. There would need to be some sort of specification in the style file or Lua script to indicate what column mapping is needed for this table, which is likely to be considerably more austere than the <code>line</code> table. It would also require considerable design work to make decisions about how to handle merging of ways when tagging disagrees on the individual ways - and, alas, the particular rendering that I have in mind for markers requires the <code>highway=*</code> tag as well as the <code>shields</code> information, so this thorny issue would have to be addressed. Moreover, I'm not entirely convinced that using this approach would save any time in rendering. The pre-merged ways might be extremely long: consider that 'network=US:I ref=87' might well merge to a single way hundreds of km long. All of the extraneous information in these monstrous ways would have to be tested against the bounding box and discarded.</p>
<p>For the reasons stated, I have a strong preference for alternative (1).</p>
<ul>
<li>Q3: Is the idea that a renderer might merge ways acceptable, and does alternative (1) look like an acceptable approach? *</li>
<li>Q3a: If not, does alternative (2), despite its disadvantages, look as if it would satisfy all requirements? *</li>
<li>Q3b: If neither of these alternative is acceptable, is there a better approach that I've missed? (Otherwise, I'm back at an impasse.) *</li>
</ul>
<p>I have not discussed yet the methods for generating the auxiliary <code>shields</code> column on initial database creation, for keeping its value consistent during database updates, or the specific database queries for driving a GroupSymbolizer to render the markers. Obviously, these methods will change based on the answers to the questions above.  I think it would likely be a waste of both my time and yours to attempt to flesh out that design before the questions above are answered.</p>
<p>I apologize for taking so much of the gatekeepers' time, but I don't see a path forward without going through requirements step by step.</p>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/openstreetmap/osm2pgsql/issues/230#issuecomment-478305268">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AD2-7r9_yi1AMvINnib67F1ShPcx_SF7ks5vcBjwgaJpZM4DGqlF">mute the thread</a>.<img src="https://github.com/notifications/beacon/AD2-7np8WZYVy1t0LqV49CZ-kgnxso0Uks5vcBjwgaJpZM4DGqlF.gif" height="1" width="1" alt="" /></p>
<script type="application/json" data-scope="inboxmarkup">{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/openstreetmap/osm2pgsql","title":"openstreetmap/osm2pgsql","subtitle":"GitHub repository","main_image_url":"https://github.githubassets.com/images/email/message_cards/header.png","avatar_image_url":"https://github.githubassets.com/images/email/message_cards/avatar.png","action":{"name":"Open in GitHub","url":"https://github.com/openstreetmap/osm2pgsql"}},"updates":{"snippets":[{"icon":"PERSON","message":"@kennykb in #230: Let me try to make one more run at breaking the log-jam.\r\n\r\nThe impasse with @lonvia appears to be that she is concerned with the performance implications of a run-time JOIN during rendering.  I begin to see how sufficiently clever preprocessing when updating the tables could avoid such a beast for the specific case of route relations. I still have questions that would influence the design of such a thing.  I'm hoping that I can get answers to them that would allow me to move forward. Otherwise, the requirement of \"come up with a fully fleshed proposal for examination\" is nearly tantamount to \"go away,\" since that is so very inefficient a method for discovering what hidden requirements a proposal must satisfy.\r\n\r\nI do get the idea of adding a 'shields' column to the database, as @lonvia suggested [earlier](https://github.com/openstreetmap/osm2pgsql/issues/230#issuecomment-426570704).  In the case of rendering concurrent routes, this column would need to comprise a delimited list of alternating values of `network` and `ref` from the route relation. (Here, I'm assuming that the type of the column must be a simple type such as INTEGER or TEXT. Obviously, if ARRAYs can be supported here, they'd be preferred!)\r\n\r\n* Q1: Is the presence of such a 'synthetic' attribute acceptable? *\r\n* Q1a: Are ARRAYs feasible here? *\r\n\r\nObviously, 'network' and 'ref' by themselves are not enough to do attractive rendering of shaped markers. I imagine that there will be additional calculation at render time to retrieve a marker and use either a `ShieldSymbolizer` or a `PointSymbolizer` to do the actual rendering (under control of a `GroupSymbolizer` to handle clusters).  This may involve an additional lookup of some sort to retrieve an appropriate graphical item. The lookup could conceivably be a JOIN operation, but in this case it would be a JOIN in which the outer table contains only items that we are already committed to rendering. This JOIN could be avoided by making the rendering decision at the time that the tables are updated, but such a design strikes me as a premature optimization and as a breaking of the division of responsibilities between database and renderer.\r\n\r\n* Q2: Is the presence of a lookup of a graphical element a showstopper? (Otherwise, I can move forward with the assumption that the 'network/ref' pair is what will be used.) *\r\n* Q2a: In the alternative, what is an appropriate way, when setting up this sort of system, to communicate the rendering rules to 'osm2pgsql' so that graphical elements can be retrieved without further database activity? *\r\n\r\nMy experience suggests that rendering of route markers can be made much more attractive and readable by coalescing ways that belong to the same routes. A route may be fragmented into a great many short ways, to represent bridges, changes in speed limits, changes in number or purpose of traffic lanes, presence or absence of cycleways or pavements, etc. Considering these short ways in isolation makes it extremely difficult to place markers at approximately equal intervals. By the same token, coalescing ways that belong to a single route means that there will be multiple ways that follow the same nodes, with no indication that they are concurrent - which was the original problem to be solved.\r\n\r\nThe correct coalescence for this particular case is to merge ways that belong to the same _set_ of route relations, rather than all ways for a given route relation.  This is _not_ consistent with how routes are stored in the `line` and `roads` tables today, and I do _not_ propose to change that, so as not to have impact on existing code that uses those tables. There are two major alternatives:\r\n\r\n(1) Simply store the `shields` information with the individual ways. At render time, once the ways have been retrieved, run ST_LineMerge on the result set (grouping by `shields` to coalesce the lines before returning them to the renderer. This method adds some computation on the database side, but is operating only on data that are known to participate in the rendering, and are already in memory buffers in PostgreSQL. Data outside the bounding box will not be considered in the merge.\r\n\r\n(2) Pre-merge the ways that correspond to each set of routes. These merged ways would need to be stored in a separate table analogous to `roads`. There would need to be some sort of specification in the style file or Lua script to indicate what column mapping is needed for this table, which is likely to be considerably more austere than the `line` table. It would also require considerable design work to make decisions about how to handle merging of ways when tagging disagrees on the individual ways - and, alas, the particular rendering that I have in mind for markers requires the `highway=*` tag as well as the `shields` information, so this thorny issue would have to be addressed. Moreover, I'm not entirely convinced that using this approach would save any time in rendering. The pre-merged ways might be extremely long: consider that 'network=US:I ref=87' might well merge to a single way hundreds of km long. All of the extraneous information in these monstrous ways would have to be tested against the bounding box and discarded.\r\n\r\nFor the reasons stated, I have a strong preference for alternative (1).\r\n\r\n* Q3: Is the idea that a renderer might merge ways acceptable, and does alternative (1) look like an acceptable approach? *\r\n* Q3a: If not, does alternative (2), despite its disadvantages, look as if it would satisfy all requirements? *\r\n* Q3b: If neither of these alternative is acceptable, is there a better approach that I've missed? (Otherwise, I'm back at an impasse.) *\r\n\r\nI have not discussed yet the methods for generating the auxiliary `shields` column on initial database creation, for keeping its value consistent during database updates, or the specific database queries for driving a GroupSymbolizer to render the markers. Obviously, these methods will change based on the answers to the questions above.  I think it would likely be a waste of both my time and yours to attempt to flesh out that design before the questions above are answered.\r\n\r\nI apologize for taking so much of the gatekeepers' time, but I don't see a path forward without going through requirements step by step. \r\n"}],"action":{"name":"View Issue","url":"https://github.com/openstreetmap/osm2pgsql/issues/230#issuecomment-478305268"}}}</script>
<script type="application/ld+json">[
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ViewAction",
"target": "https://github.com/openstreetmap/osm2pgsql/issues/230#issuecomment-478305268",
"url": "https://github.com/openstreetmap/osm2pgsql/issues/230#issuecomment-478305268",
"name": "View Issue"
},
"description": "View this Issue on GitHub",
"publisher": {
"@type": "Organization",
"name": "GitHub",
"url": "https://github.com"
}
}
]</script>