@@ -76,20 +76,21 @@ class BuildingShapeUtils extends ShapeUtils {
7676 * Walk through an array and seperate any closed ways.
7777 * Attempt to find matching open ways to enclose them.
7878 *
79- * @param {[DOM.Element] } array - list of OSM XML way elements.
79+ * @param {[DOM.Element] } ways - array of OSM XML way elements.
8080 *
8181 * @return {[DOM.Element] } array of closed ways.
8282 */
8383 static combineWays ( ways ) {
8484 const validWays = [ ] ;
8585
86+ // Check if the provided array contains any self-intersecting ways.
87+ // Remove them and notify the user.
8688 for ( const way of ways ) {
8789 if ( BuildingShapeUtils . isSelfIntersecting ( way ) ) {
8890 const id = way . getAttribute ( 'id' ) ;
8991 const msg = 'Way ' + id + ' is self-intersecting' ;
9092 window . printError ( msg ) ;
9193 } else {
92- const i = 3 + 'q' ;
9394 validWays . push ( way ) ;
9495 }
9596 }
@@ -98,6 +99,7 @@ class BuildingShapeUtils extends ShapeUtils {
9899 const wayBegins = { } ;
99100 const wayEnds = { } ;
100101
102+ // Create lists of the first and last nodes in each way.
101103 validWays . forEach ( w => {
102104 const firstNodeID = w . querySelector ( 'nd' ) . getAttribute ( 'ref' ) ;
103105 if ( wayBegins [ firstNodeID ] ) {
@@ -116,14 +118,26 @@ class BuildingShapeUtils extends ShapeUtils {
116118
117119 const usedWays = new Set ( ) ;
118120
121+ /**
122+ * Use recursion to attempt to build a ring from ways.
123+ *
124+ * @param {[DOM.Element] } currentRingWays - array of OSM XML way elements.
125+ */
119126 function tryMakeRing ( currentRingWays ) {
127+
128+ // Check if the array contains ways which will together form a ring. Return the array if it does.
120129 if ( currentRingWays [ 0 ] . querySelector ( 'nd' ) . getAttribute ( 'ref' ) ===
121130 currentRingWays [ currentRingWays . length - 1 ] . querySelector ( 'nd:last-of-type' ) . getAttribute ( 'ref' ) ) {
131+ if ( BuildingShapeUtils . isSelfIntersecting ( BuildingShapeUtils . joinAllWays ( currentRingWays ) ) ) {
132+ return [ ] ;
133+ }
122134 return currentRingWays ;
123135 }
124136
125137 const lastWay = currentRingWays [ currentRingWays . length - 1 ] ;
126138 const lastNodeID = lastWay . querySelector ( 'nd:last-of-type' ) . getAttribute ( 'ref' ) ;
139+
140+ // Check if any of the unused ways can complete a ring as the are.
127141 for ( let way of wayBegins [ lastNodeID ] ?? [ ] ) {
128142 const wayID = way . getAttribute ( 'id' ) ;
129143 if ( usedWays . has ( wayID ) ) {
@@ -138,6 +152,7 @@ class BuildingShapeUtils extends ShapeUtils {
138152 usedWays . delete ( wayID ) ;
139153 }
140154
155+ // Check if any of the unused ways can complete a ring if reversed.
141156 for ( let way of wayEnds [ lastNodeID ] ?? [ ] ) {
142157 const wayID = way . getAttribute ( 'id' ) ;
143158 if ( usedWays . has ( wayID ) ) {
@@ -163,14 +178,15 @@ class BuildingShapeUtils extends ShapeUtils {
163178 usedWays . add ( wayID ) ;
164179 const result = tryMakeRing ( [ w ] ) ;
165180 if ( result . length ) {
166- let ring = result [ 0 ] ;
167- result . slice ( 1 ) . forEach ( w => {
168- ring = this . joinWays ( ring , w ) ;
169- } ) ;
181+ const ring = this . joinAllWays ( result ) ;
170182 closedWays . push ( ring ) ;
171183 }
172184 } ) ;
173185
186+ // Notify the user if there are unused ways.
187+ // if (validWays.length !== usedWays.length) {
188+ // window.printError('Unused ways in relation')
189+ // }
174190 return closedWays ;
175191 }
176192
@@ -184,11 +200,28 @@ class BuildingShapeUtils extends ShapeUtils {
184200 */
185201 static joinWays ( way1 , way2 ) {
186202 const elements = way2 . getElementsByTagName ( 'nd' ) ;
203+ const newWay = way1 . cloneNode ( true ) ;
187204 for ( let i = 1 ; i < elements . length ; i ++ ) {
188205 let elem = elements [ i ] . cloneNode ( ) ;
189- way1 . appendChild ( elem ) ;
206+ newWay . appendChild ( elem ) ;
190207 }
191- return way1 ;
208+ return newWay ;
209+ }
210+
211+ /**
212+ * Append the nodes from one way into another.
213+ *
214+ * @param {DOM.Element } way1 - an open, non self-intersecring way
215+ * @param {DOM.Element } way2
216+ *
217+ * @return {DOM.Element } way
218+ */
219+ static joinAllWays ( ways ) {
220+ let way = ways [ 0 ] ;
221+ ways . slice ( 1 ) . forEach ( w => {
222+ way = this . joinWays ( way , w ) ;
223+ } ) ;
224+ return way ;
192225 }
193226
194227 /**
0 commit comments