Ticket #5179: osm-join-areas-6.3.patch

File osm-join-areas-6.3.patch, 221.6 KB (added by extropy, 15 years ago)

Improved existing multipolygon handling, added tests to data_nodist

  • data_nodist/Join

     
    1 <?xml version='1.0' encoding='UTF-8'?>
    2 <osm version='0.5' generator='JOSM'>
    3   <bounds minlat='49.62' minlon='8.978' maxlat='49.666' maxlon='9.02' origin='JOSM' />
    4   <node id='-671' visible='true' lat='49.632576330191526' lon='9.001884781637644' />
    5   <node id='-526' visible='true' lat='49.665557350679464' lon='8.980018030697323'>
    6     <tag k='name' v='Multipolygon' />
    7   </node>
    8   <node id='-524' visible='true' lat='49.66293444373006' lon='8.979904268383734' />
    9   <node id='-522' visible='true' lat='49.66309431357888' lon='8.98771163350794' />
    10   <node id='-520' visible='true' lat='49.66550322539429' lon='8.987481709734286' />
    11   <node id='-518' visible='true' lat='49.661140812390876' lon='8.980754551545285' />
    12   <node id='-516' visible='true' lat='49.66414787714609' lon='8.98167662069808' />
    13   <node id='-514' visible='true' lat='49.66193599760082' lon='8.983668051096597' />
    14   <node id='-512' visible='true' lat='49.66423062929877' lon='8.985896954118042' />
    15   <node id='-510' visible='true' lat='49.66122094281029' lon='8.987593944961972' />
    16   <node id='-508' visible='true' lat='49.665246272951265' lon='8.996673744036638'>
    17     <tag k='name' v='No Additional Inner Nodes' />
    18   </node>
    19   <node id='-506' visible='true' lat='49.66260897027721' lon='8.996995205661822' />
    20   <node id='-504' visible='true' lat='49.66247822670222' lon='9.006405902938653' />
    21   <node id='-502' visible='true' lat='49.66509579743186' lon='9.006492938770437' />
    22   <node id='-500' visible='true' lat='49.663673852556485' lon='9.001872836660935' />
    23   <node id='-498' visible='true' lat='49.66356462957665' lon='9.003786018319271' />
    24   <node id='-496' visible='true' lat='49.659381328509475' lon='9.002998050852923' />
    25   <node id='-494' visible='true' lat='49.658143795735675' lon='9.001321365825214' />
    26   <node id='-492' visible='true' lat='49.66102960777179' lon='9.004102187558955' />
    27   <node id='-490' visible='true' lat='49.65966007592634' lon='8.995756927212474'>
    28     <tag k='name' v='With Inner Nodes, resolve tag conflicts beforehand' />
    29   </node>
    30   <node id='-488' visible='true' lat='49.65470614469758' lon='9.000967096568774' />
    31   <node id='-486' visible='true' lat='49.658215448844345' lon='8.998101909487305' />
    32   <node id='-484' visible='true' lat='49.65482452933729' lon='8.99800181533644' />
    33   <node id='-482' visible='true' lat='49.65622420968986' lon='8.999630518959972' />
    34   <node id='-480' visible='true' lat='49.656334599426415' lon='8.99596685442522' />
    35   <node id='-478' visible='true' lat='49.664767306664714' lon='9.00358600531296' />
    36   <node id='-476' visible='true' lat='49.65595437351232' lon='9.002670090930014' />
    37   <node id='-474' visible='true' lat='49.66298227683501' lon='9.007574342263663' />
    38   <node id='-472' visible='true' lat='49.652897713964435' lon='8.995398194580462'>
    39     <tag k='name' v='Overlapping Itself' />
    40   </node>
    41   <node id='-470' visible='true' lat='49.64759565941927' lon='8.995601060044594' />
    42   <node id='-468' visible='true' lat='49.657294551336726' lon='9.005523880219158' />
    43   <node id='-466' visible='true' lat='49.65131105391522' lon='9.00298658642922' />
    44   <node id='-464' visible='true' lat='49.659323888301465' lon='9.00052935158495' />
    45   <node id='-462' visible='true' lat='49.65151745640557' lon='8.997992057795011' />
    46   <node id='-460' visible='true' lat='49.648042897844014' lon='9.003942985529385' />
    47   <node id='-458' visible='true' lat='49.64965980248303' lon='9.003039719712563' />
    48   <node id='-456' visible='true' lat='49.647526853143034' lon='8.99921412331189' />
    49   <node id='-454' visible='true' lat='49.64862774189198' lon='8.99756699152827' />
    50   <node id='-452' visible='true' lat='49.650123242376026' lon='8.984223634986959' />
    51   <node id='-450' visible='true' lat='49.6534782364111' lon='9.003730452396017' />
    52   <node id='-448' visible='true' lat='49.64965980248303' lon='8.997301325111557' />
    53   <node id='-446' visible='true' lat='49.648702988205066' lon='8.99108732452821' />
    54   <node id='-444' visible='true' lat='49.6498411096278' lon='8.989584718400737' />
    55   <node id='-442' visible='true' lat='49.64837612802103' lon='8.982669694368326' />
    56   <node id='-440' visible='true' lat='49.65267519581664' lon='8.982531354736969'>
    57     <tag k='name' v='Joining an two areas with self-overlap' />
    58   </node>
    59   <node id='-438' visible='true' lat='49.64821655131596' lon='8.986618619738293' />
    60   <node id='-436' visible='true' lat='49.65263419499493' lon='8.992015874465995' />
    61   <node id='-434' visible='true' lat='49.65180728142213' lon='8.98635078159476' />
    62   <node id='-432' visible='true' lat='49.65154365880048' lon='8.989894759403137' />
    63   <node id='-430' visible='true' lat='49.664258008517386' lon='8.994834196254615' />
    64   <node id='-428' visible='true' lat='49.66111564855195' lon='8.994837077867599' />
    65   <node id='-426' visible='true' lat='49.661575265881794' lon='9.002417415068946' />
    66   <node id='-424' visible='true' lat='49.64910487989931' lon='8.98434746261959' />
    67   <node id='-422' visible='true' lat='49.66439890567706' lon='9.000253362850133' />
    68   <node id='-420' visible='true' lat='49.66336086872286' lon='9.000172520579218' />
    69   <node id='-418' visible='true' lat='49.66163205844883' lon='8.996182583343169' />
    70   <node id='-416' visible='true' lat='49.66327697326473' lon='8.996037451903568' />
    71   <node id='-414' visible='true' lat='49.65366266054767' lon='8.983765181752341' />
    72   <node id='-412' visible='true' lat='49.65093842995153' lon='8.98362536207706' />
    73   <node id='-410' visible='true' lat='49.65083240952062' lon='8.981009751040055' />
    74   <node id='-408' visible='true' lat='49.653656418352305' lon='8.980925219001294' />
    75   <node id='-406' visible='true' lat='49.65918199608578' lon='8.97945358407826'>
    76     <tag k='name' v='Intersection already have nodes added' />
    77   </node>
    78   <node id='-404' visible='true' lat='49.65687579780412' lon='8.979558364399258' />
    79   <node id='-402' visible='true' lat='49.65684188230803' lon='8.984902160770126' />
    80   <node id='-400' visible='true' lat='49.65918199608578' lon='8.984744990288629' />
    81   <node id='-398' visible='true' lat='49.65687579780412' lon='8.980815728251226' />
    82   <node id='-396' visible='true' lat='49.65809673992071' lon='8.980815728251226' />
    83   <node id='-394' visible='true' lat='49.65792716645855' lon='8.983382846115664' />
    84   <node id='-392' visible='true' lat='49.65701145955204' lon='8.98306850515267' />
    85   <node id='-390' visible='true' lat='49.65545132661812' lon='8.981025288893223' />
    86   <node id='-388' visible='true' lat='49.65558501959522' lon='8.988437026602341' />
    87   <node id='-386' visible='true' lat='49.65931567881406' lon='8.986865321787379'>
    88     <tag k='name' v='SOME Intersection already have nodes added' />
    89   </node>
    90   <node id='-384' visible='true' lat='49.65700948686801' lon='8.986970102108378' />
    91   <node id='-382' visible='true' lat='49.65823042563044' lon='8.988227465960346' />
    92   <node id='-380' visible='true' lat='49.65931567881406' lon='8.992156727997747' />
    93   <node id='-378' visible='true' lat='49.65697557146509' lon='8.992313898479246' />
    94   <node id='-376' visible='true' lat='49.65806085263415' lon='8.990794583824783' />
    95   <node id='-374' visible='true' lat='49.65700948686801' lon='8.988227465960346' />
    96   <node id='-372' visible='true' lat='49.660221488976575' lon='8.977137289660517' />
    97   <node id='-370' visible='true' lat='49.66019710027813' lon='9.021519330497165' />
    98   <node id='-368' visible='true' lat='49.66824309940781' lon='8.99379608098765' />
    99   <node id='-366' visible='true' lat='49.665325869211465' lon='9.010629016616129'>
    100     <tag k='name' v='Member of some (i.e. not multigon) relation' />
    101   </node>
    102   <node id='-364' visible='true' lat='49.65418064466472' lon='9.02166564057246' />
    103   <node id='-362' visible='true' lat='49.66084008723247' lon='9.01744447037755' />
    104   <node id='-360' visible='true' lat='49.66089950426598' lon='9.010651964271892' />
    105   <node id='-358' visible='true' lat='49.66770174614116' lon='9.008788568211484' />
    106   <node id='-356' visible='true' lat='49.61790602056547' lon='8.993872862460284' />
    107   <node id='-354' visible='true' lat='49.654142227092336' lon='8.97793106762297' />
    108   <node id='-352' visible='true' lat='49.6179783304037' lon='9.009806812371261' />
    109   <node id='-350' visible='true' lat='49.66149367061061' lon='9.016824883671967' />
    110   <node id='-348' visible='true' lat='49.66156794089354' lon='9.014644856374543' />
    111   <node id='-346' visible='true' lat='49.6657566013461' lon='9.017559208656362' />
    112   <node id='-344' visible='true' lat='49.665266457583265' lon='9.016733093048918' />
    113   <node id='-342' visible='true' lat='49.662236368338334' lon='9.011707556436962' />
    114   <node id='-340' visible='true' lat='49.66210268358402' lon='9.017513313344837' />
    115   <node id='-338' visible='true' lat='49.663929676767346' lon='9.01471369934183' />
    116   <node id='-336' visible='true' lat='49.663989090028004' lon='9.01179934706001' />
    117   <node id='-334' visible='true' lat='49.656561909834345' lon='9.011712617586559' />
    118   <node id='-332' visible='true' lat='49.65825541574074' lon='9.014718760491427' />
    119   <node id='-330' visible='true' lat='49.65507724377221' lon='9.016274166792183' />
    120   <node id='-328' visible='true' lat='49.65831483593041' lon='9.011804408209608' />
    121   <node id='-326' visible='true' lat='49.65954150350348' lon='9.010225255249217'>
    122     <tag k='name' v='One Area already part of multipolygon (as outer)' />
    123   </node>
    124   <node id='-324' visible='true' lat='49.65948208481168' lon='9.016329331682007' />
    125   <node id='-322' visible='true' lat='49.66572689580407' lon='9.018683643788718' />
    126   <node id='-320' visible='true' lat='49.66467233731082' lon='9.018729539100242' />
    127   <node id='-318' visible='true' lat='49.650467504431084' lon='9.01556653387284' />
    128   <node id='-316' visible='true' lat='49.650467504431084' lon='9.012653673442712' />
    129   <node id='-314' visible='true' lat='49.6577783879124' lon='9.01859068072843' />
    130   <node id='-312' visible='true' lat='49.659950690584154' lon='9.018522543642344' />
    131   <node id='-310' visible='true' lat='49.659983770585875' lon='9.015660786026782' />
    132   <node id='-308' visible='true' lat='49.65777838791238' lon='9.0156778202983' />
    133   <node id='-306' visible='true' lat='49.655114612313845' lon='9.01024820290498' />
    134   <node id='-304' visible='true' lat='49.65649630973553' lon='9.01456121513066' />
    135   <node id='-302' visible='true' lat='49.649790825127035' lon='9.010994229724082' />
    136   <node id='-300' visible='true' lat='49.64907390166997' lon='9.010241166221228' />
    137   <node id='-298' visible='true' lat='49.64972521590133' lon='9.013842827268181' />
    138   <node id='-296' visible='true' lat='49.652640133446276' lon='9.015498396786755' />
    139   <node id='-294' visible='true' lat='49.65267321841768' lon='9.012636639171191' />
    140   <node id='-292' visible='true' lat='49.653441916259965' lon='9.016322294998254' />
    141   <node id='-290' visible='true' lat='49.651484566652904' lon='9.01400037262895' />
    142   <node id='-288' visible='true' lat='49.649036528490285' lon='9.01626713010843' />
    143   <node id='-286' visible='true' lat='49.64474487637503' lon='9.013313148784425' />
    144   <node id='-284' visible='true' lat='49.64329477394559' lon='9.00982115694612' />
    145   <node id='-282' visible='true' lat='49.64633804682556' lon='9.016044421132413' />
    146   <node id='-280' visible='true' lat='49.6440995060445' lon='9.015089670434026' />
    147   <node id='-278' visible='true' lat='49.64698953060391' lon='8.97763933322747' />
    148   <node id='-276' visible='true' lat='49.64702795382207' lon='9.021373906176958' />
    149   <node id='-274' visible='true' lat='49.651543995109876' lon='9.011086020347133' />
    150   <node id='-272' visible='true' lat='49.65350134232707' lon='9.010218218565463'>
    151     <tag k='name' v='One Area already part of multipolygon (as inner)' />
    152   </node>
    153   <node id='-270' visible='true' lat='49.64442618533402' lon='9.018507236795525' />
    154   <node id='-268' visible='true' lat='49.64634787643868' lon='9.01859251804108' />
    155   <node id='-266' visible='true' lat='49.646377327053195' lon='9.017591884759854' />
    156   <node id='-264' visible='true' lat='49.64446300005248' lon='9.017591884759854' />
    157   <node id='-262' visible='true' lat='49.644279396738646' lon='8.99701844322583' />
    158   <node id='-260' visible='true' lat='49.645108516691536' lon='9.00501200093294' />
    159   <node id='-258' visible='true' lat='49.64579713321828' lon='9.001725329495672' />
    160   <node id='-256' visible='true' lat='49.643570600890634' lon='9.005424239693767' />
    161   <node id='-254' visible='true' lat='49.645694403782294' lon='9.012131348650524' />
    162   <node id='-252' visible='true' lat='49.646452701397266' lon='9.00974135512665'>
    163     <tag k='name' v='Both part of other relations' />
    164   </node>
    165   <node id='-250' visible='true' lat='49.64566131406722' lon='9.01503858959705' />
    166   <node id='-248' visible='true' lat='49.64477854294109' lon='9.010865000644996' />
    167   <node id='-246' visible='true' lat='49.6436516438452' lon='9.013337536747516' />
    168   <node id='-244' visible='true' lat='49.64333102750582' lon='9.015932402078883' />
    169   <node id='-242' visible='true' lat='49.64364363066422' lon='9.010830064185653' />
    170   <node id='-240' visible='true' lat='49.6440995060445' lon='9.012176810003897' />
    171   <node id='-238' visible='true' lat='49.644215448513066' lon='8.987601210318644' />
    172   <node id='-236' visible='true' lat='49.64509437228782' lon='8.985632145182455' />
    173   <node id='-234' visible='true' lat='49.64512070290696' lon='8.990191229749867' />
    174   <node id='-232' visible='true' lat='49.64400653203681' lon='8.985527741087623' />
    175   <node id='-230' visible='true' lat='49.64362715512701' lon='8.983795590458412' />
    176   <node id='-228' visible='true' lat='49.6438359138228' lon='8.988873075900425' />
    177   <node id='-226' visible='true' lat='49.64624752120218' lon='8.990209078516749' />
    178   <node id='-224' visible='true' lat='49.64561767902291' lon='8.987111582364214' />
    179   <node id='-222' visible='true' lat='49.645870282835396' lon='9.000573288940334' />
    180   <node id='-220' visible='true' lat='49.644533441390884' lon='9.001738472218983' />
    181   <node id='-218' visible='true' lat='49.64620102922634' lon='8.995285052653605' />
    182   <node id='-216' visible='true' lat='49.645549394972946' lon='8.997512960693886' />
    183   <node id='-214' visible='true' lat='49.64390917555046' lon='9.00236900726505' />
    184   <node id='-212' visible='true' lat='49.643583272941804' lon='8.996426078862356' />
    185   <node id='-210' visible='true' lat='49.645064815871' lon='8.999528632035787' />
    186   <node id='-208' visible='true' lat='49.64660348405886' lon='9.007804150387257' />
    187   <node id='-206' visible='true' lat='49.67180165588925' lon='9.019276197911166'>
    188     <tag k='name' v='out of bounds' />
    189   </node>
    190   <node id='-204' visible='true' lat='49.66726589111355' lon='9.018808975183893' />
    191   <node id='-202' visible='true' lat='49.64294039575888' lon='8.98264180269116' />
    192   <node id='-200' visible='true' lat='49.64654691824636' lon='8.982418392157395' />
    193   <node id='-198' visible='true' lat='49.6465677851024' lon='8.992596999330347' />
    194   <node id='-196' visible='true' lat='49.64305580574678' lon='8.992869020494213' />
    195   <node id='-194' visible='true' lat='49.66722269132057' lon='9.026351284924155' />
    196   <node id='-192' visible='true' lat='49.671931242953896' lon='9.026017554404675' />
    197   <node id='-190' visible='true' lat='49.66903704959538' lon='9.022880487521558' />
    198   <node id='-188' visible='true' lat='49.664846643627826' lon='9.02334771024883' />
    199   <node id='-186' visible='true' lat='49.64619224514668' lon='8.984061673983168' />
    200   <node id='-184' visible='true' lat='49.64560080131112' lon='8.988407502515859' />
    201   <node id='-182' visible='true' lat='49.66476023970688' lon='9.029688590118962' />
    202   <node id='-180' visible='true' lat='49.6687778596993' lon='9.028553906352727' />
    203   <node id='-178' visible='true' lat='49.64226790264086' lon='9.020479682913138' />
    204   <node id='-176' visible='true' lat='49.64222947566583' lon='8.976745109963648' />
    205   <node id='-174' visible='true' lat='49.63766059241029' lon='8.985426371428245' />
    206   <node id='-172' visible='true' lat='49.64113713627012' lon='8.99764014460778' />
    207   <node id='-170' visible='true' lat='49.63620969614912' lon='8.984267584902272' />
    208   <node id='-168' visible='true' lat='49.63831098015055' lon='8.986005764691233' />
    209   <node id='-166' visible='true' lat='49.63833608786159' lon='9.001965476258553' />
    210   <node id='-164' visible='true' lat='49.63866179944343' lon='9.001060174285136' />
    211   <node id='-162' visible='true' lat='49.636707497273726' lon='8.996902491147958' />
    212   <node id='-160' visible='true' lat='49.63672921217317' lon='9.001496060420484' />
    213   <node id='-158' visible='true' lat='49.64166284075567' lon='8.990370527272402' />
    214   <node id='-156' visible='true' lat='49.64038715981111' lon='8.984846978165258' />
    215   <node id='-154' visible='true' lat='49.63635979087037' lon='8.9920314546263' />
    216   <node id='-152' visible='true' lat='49.63665997892509' lon='8.979825569886037' />
    217   <node id='-150' visible='true' lat='49.64158780162527' lon='8.984460715989934' />
    218   <node id='-148' visible='true' lat='49.63671001008765' lon='8.985696754950974' />
    219   <node id='-146' visible='true' lat='49.639336573937996' lon='8.985619502515908' />
    220   <node id='-144' visible='true' lat='49.64153777547409' lon='8.98052084180162' />
    221   <node id='-142' visible='true' lat='49.63919649619353' lon='9.000021094269913' />
    222   <node id='-140' visible='true' lat='49.63655427055324' lon='9.003685105162774' />
    223   <node id='-138' visible='true' lat='49.638889008438305' lon='9.003170088929009' />
    224   <node id='-136' visible='true' lat='49.63766439678692' lon='9.008322826347838' />
    225   <node id='-134' visible='true' lat='49.636803870494575' lon='9.005634441607576' />
    226   <node id='-132' visible='true' lat='49.64135304304343' lon='9.008042625328157' />
    227   <node id='-130' visible='true' lat='49.641397690721426' lon='9.002032535663991' />
    228   <node id='-128' visible='true' lat='49.639702839791006' lon='9.002946110514843' />
    229   <node id='-126' visible='true' lat='49.641505032635514' lon='9.005561427326938' />
    230   <node id='-124' visible='true' lat='49.640355464550595' lon='9.000557228744347' />
    231   <node id='-122' visible='true' lat='49.63983876223289' lon='8.999763400318008' />
    232   <node id='-120' visible='true' lat='49.640963432528' lon='9.002300773285747' />
    233   <node id='-118' visible='true' lat='49.640355464550595' lon='9.00163017923136' />
    234   <node id='-116' visible='true' lat='49.641650361020126' lon='9.011375542032631' />
    235   <node id='-114' visible='true' lat='49.63994510769946' lon='9.011537754906723' />
    236   <node id='-112' visible='true' lat='49.63989778320692' lon='9.01301762121565' />
    237   <node id='-110' visible='true' lat='49.63851559945754' lon='9.011923928883068' />
    238   <node id='-108' visible='true' lat='49.63931004998166' lon='9.014994879645652' />
    239   <node id='-106' visible='true' lat='49.63656290879177' lon='9.01184224653937' />
    240   <node id='-104' visible='true' lat='49.638495992538296' lon='9.013041516659012' />
    241   <node id='-102' visible='true' lat='49.639297465489946' lon='9.013075043737933' />
    242   <node id='-100' visible='true' lat='49.63932787364639' lon='9.011341760369241' />
    243   <node id='-98' visible='true' lat='49.6362341674196' lon='9.011212347946481' />
    244   <node id='-96' visible='true' lat='49.63846974351432' lon='9.014959728094702' />
    245   <node id='-94' visible='true' lat='49.639285639926086' lon='9.016386267202325' />
    246   <node id='-92' visible='true' lat='49.63614569649766' lon='9.016254920813461' />
    247   <node id='-90' visible='true' lat='49.636497278618506' lon='9.01558299248487' />
    248   <node id='-88' visible='true' lat='49.64173715249402' lon='9.01288893804428' />
    249   <node id='-86' visible='true' lat='49.63997057825359' lon='9.017121223877993' />
    250   <node id='-84' visible='true' lat='49.6418769973781' lon='9.016690773382148' />
    251   <node id='-82' visible='true' lat='49.638457370514' lon='9.015664984322639' />
    252   <node id='-80' visible='true' lat='49.631502879910435' lon='8.984843899814363' />
    253   <node id='-78' visible='true' lat='49.63276591351912' lon='8.988186843940152' />
    254   <node id='-76' visible='true' lat='49.63332524651039' lon='8.982503838926318' />
    255   <node id='-74' visible='true' lat='49.631033744799794' lon='8.984788184078935' />
    256   <node id='-72' visible='true' lat='49.63087135082409' lon='8.987936123130721' />
    257   <node id='-70' visible='true' lat='49.632224617411495' lon='8.98487175768208' />
    258   <node id='-68' visible='true' lat='49.63191788028032' lon='8.988911148500739' />
    259   <node id='-66' visible='true' lat='49.63282112167936' lon='8.984873752905482' />
    260   <node id='-64' visible='true' lat='49.629896975600474' lon='8.982336691720024' />
    261   <node id='-62' visible='true' lat='49.633361332289276' lon='8.984899615549795' />
    262   <node id='-60' visible='true' lat='49.63146679275468' lon='8.988019696733868' />
    263   <node id='-58' visible='true' lat='49.63204418403885' lon='8.988131128204722' />
    264   <node id='-56' visible='true' lat='49.629734577834874' lon='8.988799717029881' />
    265   <node id='-54' visible='true' lat='49.62984284307208' lon='8.984760326211225' />
    266   <node id='-52' visible='true' lat='49.633235031946306' lon='8.989050437839317' />
    267   <node id='-50' visible='true' lat='49.634715291319765' lon='8.977209351682495' />
    268   <node id='-48' visible='true' lat='49.6347537242248' lon='9.020943924631984' />
    269   <node id='-46' visible='true' lat='49.62789803392637' lon='8.977125941387275' />
    270   <node id='-44' visible='true' lat='49.62793647221095' lon='9.020860514336768' />
    271   <node id='-42' visible='true' lat='49.633374730988635' lon='9.000934610919133' />
    272   <node id='-40' visible='true' lat='49.6315080216117' lon='8.997138044228079' />
    273   <node id='-38' visible='true' lat='49.631610067691966' lon='9.003079417313643' />
    274   <node id='-36' visible='true' lat='49.629711140902785' lon='8.999277013032064' />
    275   <node id='-34' visible='true' lat='49.63246699537921' lon='8.999116354145995' />
    276   <node id='-32' visible='true' lat='49.632576330191526' lon='9.001884781637644' />
    277   <node id='-30' visible='true' lat='49.633942630142286' lon='9.011036145015492' />
    278   <node id='-28' visible='true' lat='49.63397051736248' lon='9.010775661985484' />
    279   <node id='-26' visible='true' lat='49.63376409638575' lon='9.010301073275484' />
    280   <node id='-24' visible='true' lat='49.63394262769327' lon='9.011036375275484' />
    281   <node id='-22' visible='true' lat='49.63389375219822' lon='9.010963515015485' />
    282   <node id='-20' visible='true' lat='49.633856212166755' lon='9.010893473725478' />
    283   <node id='-18' visible='true' lat='49.63394377111033' lon='9.010928613485484' />
    284   <node id='-16' visible='true' lat='49.63365009319664' lon='9.01041866293549' />
    285   <node id='-14' visible='true' lat='49.6339376312857' lon='9.010915330605481' />
    286   <node id='-12' visible='true' lat='49.6339459893696' lon='9.010719537165489' />
    287   <node id='-10' visible='true' lat='49.633945127068216' lon='9.010800819035481' />
    288   <node id='-8' visible='true' lat='49.63397651971739' lon='9.010999225285477' />
    289   <node id='-6' visible='true' lat='49.63393264307744' lon='9.011047179395488' />
    290   <node id='-4' visible='true' lat='49.633945117271765' lon='9.010801740085483' />
    291   <node id='-2' visible='true' lat='49.634297623749426' lon='9.009913613166118'>
    292     <tag k='name' v='two nodes are overlapping, but not identical' />
    293   </node>
    294   <way id='-642' visible='true'>
    295     <nd ref='-186' />
    296     <nd ref='-226' />
    297     <nd ref='-234' />
    298     <nd ref='-236' />
    299     <nd ref='-232' />
    300     <nd ref='-238' />
    301     <nd ref='-224' />
    302     <nd ref='-184' />
    303     <nd ref='-228' />
    304     <nd ref='-230' />
    305     <nd ref='-186' />
    306     <tag k='name' v='Thing in the Middle' />
    307   </way>
    308   <way id='-640' visible='true'>
    309     <nd ref='-200' />
    310     <nd ref='-202' />
    311     <nd ref='-196' />
    312     <nd ref='-198' />
    313     <nd ref='-200' />
    314     <tag k='amenity' v='parking' />
    315     <tag k='name' v='Outer blob' />
    316     <tag k='parking' v='surface' />
    317   </way>
    318   <way id='-638' visible='true'>
    319     <nd ref='-294' />
    320     <nd ref='-316' />
    321     <nd ref='-318' />
    322     <nd ref='-296' />
    323     <nd ref='-294' />
    324   </way>
    325   <way id='-636' visible='true'>
    326     <nd ref='-472' />
    327     <nd ref='-450' />
    328     <nd ref='-460' />
    329     <nd ref='-454' />
    330     <nd ref='-448' />
    331     <nd ref='-458' />
    332     <nd ref='-466' />
    333     <nd ref='-462' />
    334     <nd ref='-456' />
    335     <nd ref='-470' />
    336     <nd ref='-472' />
    337     <tag k='amenity' v='parking' />
    338     <tag k='parking' v='surface' />
    339   </way>
    340   <way id='-634' visible='true'>
    341     <nd ref='-212' />
    342     <nd ref='-218' />
    343     <nd ref='-208' />
    344     <nd ref='-256' />
    345     <nd ref='-212' />
    346     <tag k='amenity' v='parking' />
    347     <tag k='parking' v='surface' />
    348   </way>
    349   <way id='-632' visible='true'>
    350     <nd ref='-310' />
    351     <nd ref='-308' />
    352     <nd ref='-314' />
    353     <nd ref='-312' />
    354     <nd ref='-310' />
    355   </way>
    356   <way id='-630' visible='true'>
    357     <nd ref='-388' />
    358     <nd ref='-374' />
    359     <nd ref='-382' />
    360     <nd ref='-376' />
    361     <nd ref='-388' />
    362     <tag k='amenity' v='parking' />
    363     <tag k='parking' v='surface' />
    364   </way>
    365   <way id='-628' visible='true'>
    366     <nd ref='-508' />
    367     <nd ref='-506' />
    368     <nd ref='-504' />
    369     <nd ref='-502' />
    370     <nd ref='-508' />
    371     <tag k='amenity' v='parking' />
    372     <tag k='parking' v='surface' />
    373   </way>
    374   <way id='-626' visible='true'>
    375     <nd ref='-330' />
    376     <nd ref='-324' />
    377     <nd ref='-326' />
    378     <nd ref='-306' />
    379     <nd ref='-330' />
    380     <tag k='amenity' v='parking' />
    381     <tag k='parking' v='surface' />
    382   </way>
    383   <way id='-624' visible='true'>
    384     <nd ref='-132' />
    385     <nd ref='-126' />
    386     <nd ref='-130' />
    387     <nd ref='-120' />
    388     <nd ref='-118' />
    389     <nd ref='-128' />
    390     <nd ref='-138' />
    391     <nd ref='-166' />
    392     <nd ref='-160' />
    393     <nd ref='-140' />
    394     <nd ref='-134' />
    395     <nd ref='-136' />
    396     <nd ref='-132' />
    397     <tag k='amenity' v='parking' />
    398     <tag k='parking' v='surface' />
    399   </way>
    400   <way id='-622' visible='true'>
    401     <nd ref='-406' />
    402     <nd ref='-404' />
    403     <nd ref='-398' />
    404     <nd ref='-392' />
    405     <nd ref='-402' />
    406     <nd ref='-400' />
    407     <nd ref='-406' />
    408     <tag k='amenity' v='parking' />
    409     <tag k='parking' v='surface' />
    410   </way>
    411   <way id='-620' visible='true'>
    412     <nd ref='-366' />
    413     <nd ref='-360' />
    414     <nd ref='-362' />
    415     <nd ref='-340' />
    416     <nd ref='-342' />
    417     <nd ref='-336' />
    418     <nd ref='-338' />
    419     <nd ref='-348' />
    420     <nd ref='-350' />
    421     <nd ref='-344' />
    422     <nd ref='-366' />
    423     <tag k='amenity' v='parking' />
    424     <tag k='parking' v='surface' />
    425   </way>
    426   <way id='-618' visible='true'>
    427     <nd ref='-440' />
    428     <nd ref='-436' />
    429     <nd ref='-446' />
    430     <nd ref='-424' />
    431     <nd ref='-452' />
    432     <nd ref='-444' />
    433     <nd ref='-432' />
    434     <nd ref='-434' />
    435     <nd ref='-438' />
    436     <nd ref='-442' />
    437     <nd ref='-440' />
    438     <tag k='amenity' v='parking' />
    439     <tag k='parking' v='surface' />
    440   </way>
    441   <way id='-616' visible='true'>
    442     <nd ref='-304' />
    443     <nd ref='-334' />
    444     <nd ref='-328' />
    445     <nd ref='-332' />
    446     <nd ref='-304' />
    447   </way>
    448   <way id='-614' visible='true'>
    449     <nd ref='-288' />
    450     <nd ref='-292' />
    451     <nd ref='-272' />
    452     <nd ref='-300' />
    453     <nd ref='-288' />
    454     <tag k='amenity' v='parking' />
    455     <tag k='parking' v='surface' />
    456   </way>
    457   <way id='-612' visible='true'>
    458     <nd ref='-372' />
    459     <nd ref='-370' />
    460     <tag k='highway' v='motorway' />
    461     <tag k='lanes' v='5' />
    462   </way>
    463   <way id='-610' visible='true'>
    464     <nd ref='-478' />
    465     <nd ref='-498' />
    466     <nd ref='-474' />
    467     <tag k='highway' v='footway' />
    468   </way>
    469   <way id='-608' visible='true'>
    470     <nd ref='-278' />
    471     <nd ref='-276' />
    472     <tag k='highway' v='motorway' />
    473     <tag k='lanes' v='5' />
    474   </way>
    475   <way id='-606' visible='true'>
    476     <nd ref='-144' />
    477     <nd ref='-150' />
    478     <nd ref='-156' />
    479     <nd ref='-146' />
    480     <nd ref='-168' />
    481     <nd ref='-174' />
    482     <nd ref='-148' />
    483     <nd ref='-170' />
    484     <nd ref='-152' />
    485     <nd ref='-144' />
    486     <tag k='amenity' v='parking' />
    487   </way>
    488   <way id='-604' visible='true'>
    489     <nd ref='-408' />
    490     <nd ref='-410' />
    491     <nd ref='-412' />
    492     <nd ref='-414' />
    493     <nd ref='-408' />
    494     <tag k='amenity' v='parking' />
    495     <tag k='parking' v='surface' />
    496   </way>
    497   <way id='-602' visible='true'>
    498     <nd ref='-346' />
    499     <nd ref='-322' />
    500     <nd ref='-320' />
    501   </way>
    502   <way id='-600' visible='true'>
    503     <nd ref='-112' />
    504     <nd ref='-86' />
    505     <nd ref='-84' />
    506     <nd ref='-88' />
    507     <nd ref='-112' />
    508     <tag k='amenity' v='parking' />
    509     <tag k='parking' v='surface' />
    510   </way>
    511   <way id='-598' visible='true'>
    512     <nd ref='-484' />
    513     <nd ref='-486' />
    514     <nd ref='-494' />
    515     <nd ref='-488' />
    516     <nd ref='-484' />
    517     <tag k='landuse' v='basin' />
    518   </way>
    519   <way id='-596' visible='true'>
    520     <nd ref='-158' />
    521     <nd ref='-150' />
    522     <nd ref='-156' />
    523     <nd ref='-146' />
    524     <nd ref='-168' />
    525     <nd ref='-174' />
    526     <nd ref='-148' />
    527     <nd ref='-170' />
    528     <nd ref='-154' />
    529     <nd ref='-158' />
    530     <tag k='amenity' v='parking' />
    531   </way>
    532   <way id='-594' visible='true'>
    533     <nd ref='-518' />
    534     <nd ref='-516' />
    535     <nd ref='-514' />
    536     <nd ref='-512' />
    537     <nd ref='-510' />
    538     <nd ref='-518' />
    539     <tag k='amenity' v='parking' />
    540     <tag k='parking' v='surface' />
    541   </way>
    542   <way id='-592' visible='true'>
    543     <nd ref='-96' />
    544     <nd ref='-108' />
    545     <nd ref='-102' />
    546     <nd ref='-104' />
    547     <nd ref='-96' />
    548     <tag k='building' v='yes' />
    549   </way>
    550   <way id='-590' visible='true'>
    551     <nd ref='-172' />
    552     <nd ref='-162' />
    553     <nd ref='-160' />
    554     <nd ref='-166' />
    555     <nd ref='-164' />
    556     <nd ref='-142' />
    557     <nd ref='-122' />
    558     <nd ref='-124' />
    559     <nd ref='-118' />
    560     <nd ref='-120' />
    561     <nd ref='-130' />
    562     <nd ref='-172' />
    563     <tag k='amenity' v='parking' />
    564     <tag k='parking' v='surface' />
    565   </way>
    566   <way id='-588' visible='true'>
    567     <nd ref='-354' />
    568     <nd ref='-364' />
    569     <tag k='highway' v='motorway' />
    570     <tag k='lanes' v='5' />
    571   </way>
    572   <way id='-586' visible='true'>
    573     <nd ref='-222' />
    574     <nd ref='-220' />
    575     <nd ref='-262' />
    576     <nd ref='-216' />
    577     <nd ref='-222' />
    578   </way>
    579   <way id='-584' visible='true'>
    580     <nd ref='-268' />
    581     <nd ref='-270' />
    582     <nd ref='-264' />
    583     <nd ref='-266' />
    584     <nd ref='-268' />
    585   </way>
    586   <way id='-582' visible='true'>
    587     <nd ref='-298' />
    588     <nd ref='-302' />
    589     <nd ref='-274' />
    590     <nd ref='-290' />
    591     <nd ref='-298' />
    592   </way>
    593   <way id='-580' visible='true'>
    594     <nd ref='-254' />
    595     <nd ref='-240' />
    596     <nd ref='-280' />
    597     <nd ref='-250' />
    598     <nd ref='-254' />
    599   </way>
    600   <way id='-578' visible='true'>
    601     <nd ref='-464' />
    602     <nd ref='-494' />
    603     <nd ref='-468' />
    604     <tag k='highway' v='footway' />
    605   </way>
    606   <way id='-576' visible='true'>
    607     <nd ref='-108' />
    608     <nd ref='-94' />
    609     <nd ref='-92' />
    610     <nd ref='-98' />
    611     <nd ref='-100' />
    612     <nd ref='-102' />
    613     <nd ref='-104' />
    614     <nd ref='-110' />
    615     <nd ref='-106' />
    616     <nd ref='-90' />
    617     <nd ref='-82' />
    618     <nd ref='-96' />
    619     <nd ref='-108' />
    620     <tag k='building' v='yes' />
    621   </way>
    622   <way id='-574' visible='true'>
    623     <nd ref='-206' />
    624     <nd ref='-204' />
    625     <nd ref='-194' />
    626     <nd ref='-192' />
    627     <nd ref='-206' />
    628     <tag k='amenity' v='parking' />
    629     <tag k='parking' v='surface' />
    630   </way>
    631   <way id='-572' visible='true'>
    632     <nd ref='-116' />
    633     <nd ref='-114' />
    634     <nd ref='-112' />
    635     <nd ref='-88' />
    636     <nd ref='-116' />
    637     <tag k='amenity' v='parking' />
    638     <tag k='parking' v='surface' />
    639   </way>
    640   <way id='-570' visible='true'>
    641     <nd ref='-190' />
    642     <nd ref='-188' />
    643     <nd ref='-182' />
    644     <nd ref='-180' />
    645     <nd ref='-190' />
    646     <tag k='amenity' v='parking' />
    647     <tag k='parking' v='surface' />
    648   </way>
    649   <way id='-568' visible='true'>
    650     <nd ref='-210' />
    651     <nd ref='-258' />
    652     <nd ref='-260' />
    653     <nd ref='-214' />
    654     <nd ref='-210' />
    655   </way>
    656   <way id='-566' visible='true'>
    657     <nd ref='-246' />
    658     <nd ref='-242' />
    659     <nd ref='-248' />
    660     <nd ref='-286' />
    661     <nd ref='-246' />
    662   </way>
    663   <way id='-564' visible='true'>
    664     <nd ref='-492' />
    665     <nd ref='-428' />
    666     <nd ref='-430' />
    667     <nd ref='-422' />
    668     <nd ref='-420' />
    669     <nd ref='-416' />
    670     <nd ref='-418' />
    671     <nd ref='-426' />
    672     <nd ref='-500' />
    673     <nd ref='-498' />
    674     <nd ref='-492' />
    675     <tag k='amenity' v='parking' />
    676     <tag k='parking' v='surface' />
    677   </way>
    678   <way id='-562' visible='true'>
    679     <nd ref='-176' />
    680     <nd ref='-178' />
    681     <tag k='highway' v='motorway' />
    682     <tag k='lanes' v='5' />
    683   </way>
    684   <way id='-560' visible='true'>
    685     <nd ref='-476' />
    686     <nd ref='-496' />
    687     <nd ref='-490' />
    688     <nd ref='-480' />
    689     <nd ref='-482' />
    690     <nd ref='-476' />
    691     <tag k='landuse' v='retail' />
    692   </way>
    693   <way id='-558' visible='true'>
    694     <nd ref='-386' />
    695     <nd ref='-384' />
    696     <nd ref='-374' />
    697     <nd ref='-378' />
    698     <nd ref='-380' />
    699     <nd ref='-386' />
    700     <tag k='amenity' v='parking' />
    701     <tag k='parking' v='surface' />
    702   </way>
    703   <way id='-556' visible='true'>
    704     <nd ref='-358' />
    705     <nd ref='-352' />
    706     <tag k='highway' v='motorway' />
    707     <tag k='lanes' v='5' />
    708   </way>
    709   <way id='-554' visible='true'>
    710     <nd ref='-368' />
    711     <nd ref='-356' />
    712     <tag k='highway' v='motorway' />
    713     <tag k='lanes' v='5' />
    714   </way>
    715   <way id='-552' visible='true'>
    716     <nd ref='-244' />
    717     <nd ref='-282' />
    718     <nd ref='-252' />
    719     <nd ref='-284' />
    720     <nd ref='-244' />
    721     <tag k='amenity' v='parking' />
    722     <tag k='parking' v='surface' />
    723   </way>
    724   <way id='-550' visible='true'>
    725     <nd ref='-390' />
    726     <nd ref='-398' />
    727     <nd ref='-396' />
    728     <nd ref='-394' />
    729     <nd ref='-392' />
    730     <nd ref='-390' />
    731     <tag k='amenity' v='parking' />
    732     <tag k='parking' v='surface' />
    733   </way>
    734   <way id='-548' visible='true'>
    735     <nd ref='-526' />
    736     <nd ref='-524' />
    737     <nd ref='-522' />
    738     <nd ref='-520' />
    739     <nd ref='-526' />
    740     <tag k='amenity' v='parking' />
    741     <tag k='parking' v='surface' />
    742   </way>
    743   <way id='-546' visible='true'>
    744     <nd ref='-62' />
    745     <nd ref='-52' />
    746     <nd ref='-68' />
    747     <nd ref='-56' />
    748     <nd ref='-54' />
    749     <nd ref='-74' />
    750     <nd ref='-72' />
    751     <nd ref='-60' />
    752     <nd ref='-80' />
    753     <nd ref='-70' />
    754     <nd ref='-58' />
    755     <nd ref='-78' />
    756     <nd ref='-66' />
    757     <nd ref='-62' />
    758     <tag k='building' v='yes' />
    759   </way>
    760   <way id='-544' visible='true'>
    761     <nd ref='-76' />
    762     <nd ref='-64' />
    763     <nd ref='-54' />
    764     <nd ref='-74' />
    765     <nd ref='-80' />
    766     <nd ref='-70' />
    767     <nd ref='-66' />
    768     <nd ref='-62' />
    769     <nd ref='-76' />
    770     <tag k='building' v='yes' />
    771   </way>
    772   <way id='-542' visible='true'>
    773     <nd ref='-50' />
    774     <nd ref='-48' />
    775     <tag k='highway' v='motorway' />
    776     <tag k='lanes' v='5' />
    777   </way>
    778   <way id='-540' visible='true'>
    779     <nd ref='-46' />
    780     <nd ref='-44' />
    781     <tag k='highway' v='motorway' />
    782     <tag k='lanes' v='5' />
    783   </way>
    784   <way id='-538' visible='true'>
    785     <nd ref='-32' />
    786     <nd ref='-38' />
    787     <nd ref='-36' />
    788     <nd ref='-40' />
    789     <nd ref='-34' />
    790     <nd ref='-32' />
    791     <tag k='building' v='yes' />
    792     <tag k='name' v='A' />
    793   </way>
    794   <way id='-536' visible='true'>
    795     <nd ref='-34' />
    796     <nd ref='-42' />
    797     <nd ref='-671' />
    798     <nd ref='-34' />
    799     <tag k='building' v='yes' />
    800     <tag k='name' v='A' />
    801   </way>
    802   <way id='-534' visible='true'>
    803     <nd ref='-30' />
    804     <nd ref='-6' />
    805     <nd ref='-22' />
    806     <nd ref='-14' />
    807     <nd ref='-18' />
    808     <nd ref='-30' />
    809     <tag k='building' v='yes' />
    810     <tag k='name' v='B' />
    811   </way>
    812   <way id='-532' visible='true'>
    813     <nd ref='-18' />
    814     <nd ref='-8' />
    815     <nd ref='-24' />
    816     <nd ref='-18' />
    817     <tag k='building' v='yes' />
    818     <tag k='name' v='B' />
    819   </way>
    820   <way id='-530' visible='true'>
    821     <nd ref='-4' />
    822     <nd ref='-20' />
    823     <nd ref='-16' />
    824     <nd ref='-26' />
    825     <nd ref='-12' />
    826     <nd ref='-4' />
    827     <tag k='building' v='yes' />
    828     <tag k='name' v='A' />
    829   </way>
    830   <way id='-528' visible='true'>
    831     <nd ref='-12' />
    832     <nd ref='-28' />
    833     <nd ref='-10' />
    834     <nd ref='-12' />
    835     <tag k='building' v='yes' />
    836     <tag k='name' v='A' />
    837   </way>
    838   <relation id='-658' visible='true'>
    839     <member type='way' ref='-642' role='inner' />
    840     <member type='way' ref='-640' role='outer' />
    841     <tag k='name' v='6.' />
    842     <tag k='type' v='multipolygon' />
    843   </relation>
    844   <relation id='-656' visible='true'>
    845     <member type='way' ref='-586' role='inner' />
    846     <member type='way' ref='-568' role='inner' />
    847     <member type='way' ref='-634' role='outer' />
    848     <tag k='name' v='5.' />
    849     <tag k='type' v='multipolygon' />
    850   </relation>
    851   <relation id='-654' visible='true'>
    852     <member type='way' ref='-566' role='inner' />
    853     <member type='way' ref='-552' role='outer' />
    854     <tag k='name' v='4. a' />
    855     <tag k='type' v='multipolygon' />
    856   </relation>
    857   <relation id='-652' visible='true'>
    858     <member type='way' ref='-616' role='inner' />
    859     <member type='way' ref='-626' role='outer' />
    860     <tag k='name' v='2.' />
    861     <tag k='type' v='multipolygon' />
    862   </relation>
    863   <relation id='-650' visible='true'>
    864   </relation>
    865   <relation id='-648' visible='true'>
    866     <member type='way' ref='-584' role='' />
    867     <member type='way' ref='-580' role='' />
    868     <tag k='name ' v='4. b' />
    869   </relation>
    870   <relation id='-646' visible='true'>
    871     <member type='way' ref='-582' role='inner' />
    872     <member type='way' ref='-614' role='outer' />
    873     <tag k='name' v='3.' />
    874     <tag k='type' v='multipolygon' />
    875   </relation>
    876   <relation id='-644' visible='true'>
    877     <member type='way' ref='-620' role='area' />
    878     <member type='node' ref='-342' role='node in area' />
    879     <member type='node' ref='-338' role='node in area' />
    880     <member type='way' ref='-602' role='some other way' />
    881     <member type='node' ref='-348' role='to be deleted node in area' />
    882     <tag k='name' v='1.' />
    883   </relation>
    884 </osm>
     1<?xml version='1.0' encoding='UTF-8'?>
     2<osm version='0.5' generator='JOSM'>
     3  <bounds minlat='49.12' minlon='8.978' maxlat='49.666' maxlon='9.02' origin='JOSM' />
     4  <node id='-1591' action='modify' visible='true' lat='49.59121281152023' lon='9.010296308747527' />
     5  <node id='-1589' visible='true' lat='49.591520046570636' lon='9.008427711684268' />
     6  <node id='-1587' visible='true' lat='49.59619452427462' lon='9.009193530152816' />
     7  <node id='-1585' action='modify' visible='true' lat='49.5955497763459' lon='9.019888610520818' />
     8  <node id='-1583' visible='true' lat='49.591106354399614' lon='9.019000261097299' />
     9  <node id='-1581' visible='true' lat='49.591106354399614' lon='9.01755371510115' />
     10  <node id='-1579' visible='true' lat='49.59154762592395' lon='9.017830260659236' />
     11  <node id='-1577' visible='true' lat='49.59219573623785' lon='9.01036353059088' />
     12  <node id='-1575' visible='true' lat='49.59247152524883' lon='9.010257166914691' />
     13  <node id='-1573' visible='true' lat='49.59193373523305' lon='9.018000442541137' />
     14  <node id='-1571' visible='true' lat='49.59236120983157' lon='9.018064260746849' />
     15  <node id='-1569' visible='true' lat='49.592774891359845' lon='9.010065712297555' />
     16  <node id='-1567' visible='true' lat='49.59517417503492' lon='9.010384803326117' />
     17  <node id='-1565' visible='true' lat='49.59466399240977' lon='9.018808806480163' />
     18  <node id='-1563' visible='true' lat='49.59322993698855' lon='9.018064260746849' />
     19  <node id='-1561' visible='true' lat='49.593878024948886' lon='9.011661167440366' />
     20  <node id='-1559' visible='true' lat='49.594402004663465' lon='9.011788803851791' />
     21  <node id='-1557' visible='true' lat='49.59418138231186' lon='9.017596260571624' />
     22  <node id='-1555' visible='true' lat='49.59380907983053' lon='9.017596260571624' />
     23  <node id='-1553' visible='true' lat='49.5942227490788' lon='9.01280989514319' />
     24  <node id='-1551' visible='true' lat='49.59383665788956' lon='9.012724804202241' />
     25  <node id='-1549' visible='true' lat='49.593464352776806' lon='9.017851533394474' />
     26  <node id='-1547' visible='true' lat='49.59434684916912' lon='9.018213169893512' />
     27  <node id='-1545' visible='true' lat='49.594650203616105' lon='9.010959167177528' />
     28  <node id='-1543' visible='true' lat='49.59367118930141' lon='9.010874076236579' />
     29  <node id='-1541' visible='true' lat='49.59274731270045' lon='9.018766261009686' />
     30  <node id='-1539' visible='true' lat='49.59539479289559' lon='9.019468261272523' />
     31  <node id='-1537' visible='true' lat='49.59583602562297' lon='9.00951262118138' />
     32  <node id='-1535' visible='true' lat='49.59207163067417' lon='9.008938257329968' />
     33  <node id='-1533' visible='true' lat='49.59073402844584' lon='9.017915351600188' />
     34  <node id='-1531' visible='true' lat='49.588596546686055' lon='9.016979351249736' />
     35  <node id='-1528' visible='true' lat='49.58925848653267' lon='9.011682440175603' />
     36  <node id='-1526' visible='true' lat='49.5960566404897' lon='9.013022622495564' />
     37  <node id='-1524' visible='true' lat='49.59578087175036' lon='9.01721335133735' />
     38  <node id='-1522' visible='true' lat='49.5898376765303' lon='9.015298805165976' />
     39  <node id='-1520' visible='true' lat='49.5902927495612' lon='9.012831167878428' />
     40  <node id='-1518' visible='true' lat='49.595574044172544' lon='9.013852259169827' />
     41  <node id='-1516' visible='true' lat='49.595463735772384' lon='9.016043350899286' />
     42  <node id='-1514' visible='true' lat='49.59049959953543' lon='9.01466062310885' />
     43  <node id='-1512' visible='true' lat='49.59074781834665' lon='9.013788440964115' />
     44  <node id='-1510' visible='true' lat='49.59511902041382' lon='9.01476698678504' />
     45  <node id='-1508' visible='true' lat='49.59511902041382' lon='9.015086077813601' />
     46  <node id='-1506' visible='true' lat='49.5909408765488' lon='9.013979895581251' />
     47  <node id='-1504' visible='true' lat='49.590789188025724' lon='9.014511713962188' />
     48  <node id='-1502' visible='true' lat='49.59535342712273' lon='9.015724259870726' />
     49  <node id='-1500' visible='true' lat='49.595381004308535' lon='9.014426623021238' />
     50  <node id='-1498' visible='true' lat='49.59045822961075' lon='9.013469349935553' />
     51  <node id='-1496' visible='true' lat='49.590182429216284' lon='9.0149158959317' />
     52  <node id='-1494' visible='true' lat='49.59567056381802' lon='9.016596442015464' />
     53  <node id='-1492' visible='true' lat='49.59589117943322' lon='9.013426804465077' />
     54  <node id='-1490' visible='true' lat='49.589879046981274' lon='9.012107894880351' />
     55  <node id='-1488' visible='true' lat='49.58923090588506' lon='9.015639168929775' />
     56  <node id='-1486' visible='true' lat='49.59618239051721' lon='9.01791535160019' />
     57  <node id='-1484' visible='true' lat='49.59619121506835' lon='9.01267374963767' />
     58  <node id='-1482' visible='true' lat='49.58999598726625' lon='9.011557356492407' />
     59  <node id='-1480' visible='true' lat='49.59286424610918' lon='9.009692163066786' />
     60  <node id='-1478' visible='true' lat='49.59537934967783' lon='9.01628160553395' />
     61  <node id='-1476' visible='true' lat='49.59367615336723' lon='9.018596079127787' />
     62  <node id='-1474' visible='true' lat='49.59127569281911' lon='9.013014113401471' />
     63  <node id='-1472' visible='true' lat='49.59266126718291' lon='9.01177518930124' />
     64  <node id='-1470' visible='true' lat='49.59432919939776' lon='9.015941241770149' />
     65  <node id='-1468' visible='true' lat='49.59377322833046' lon='9.016921489409894' />
     66  <node id='-1466' visible='true' lat='49.592290607833576' lon='9.013679524559699' />
     67  <node id='-1464' visible='true' lat='49.59251123873798' lon='9.013445524472088' />
     68  <node id='-1462' visible='true' lat='49.59382121417842' lon='9.016359889199624' />
     69  <node id='-1460' visible='true' lat='49.594014260216206' lon='9.01595570723011' />
     70  <node id='-1458' visible='true' lat='49.59262155381594' lon='9.012637160533064' />
     71  <node id='-1456' visible='true' lat='49.591697657332844' lon='9.013509342677802' />
     72  <node id='-1454' visible='true' lat='49.59377984707092' lon='9.018061708018623' />
     73  <node id='-1452' visible='true' lat='49.59466233775474' lon='9.0160620709063' />
     74  <node id='-1450' visible='true' lat='49.59278702596504' lon='9.010956614449302' />
     75  <node id='-1448' visible='true' lat='49.59078753323923' lon='9.012849887885437' />
     76  <node id='-1446' visible='true' lat='49.593614378290034' lon='9.019401890338584' />
     77  <node id='-1444' visible='true' lat='49.595944678569566' lon='9.016466252875812' />
     78  <node id='-1443' action='modify' visible='true' lat='49.59368056586976' lon='9.010546476113923' />
     79  <node id='-1168' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.607803062119885' lon='9.016707564670496' />
     80  <node id='-1166' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60899890998874' lon='9.017529615751378' />
     81  <node id='-1164' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.607737833210614' lon='9.014107199006487' />
     82  <node id='-1162' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60774870470155' lon='9.015499652878182' />
     83  <node id='-1160' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60899890998874' lon='9.01613716187968' />
     84  <node id='-1158' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.6089119402238' lon='9.014610495586618' />
     85  <node id='-1156' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60881409905279' lon='9.013067052740885' />
     86  <node id='-1154' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.59746171082487' lon='9.020319348694485' />
     87  <node id='-1152' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.5974232484995' lon='8.974946440523215' />
     88  <node id='-1150' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60035810797174' lon='9.014756256613616' />
     89  <node id='-1148' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.600761601650554' lon='9.01754142649064' />
     90  <node id='-1146' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.6021631853287' lon='9.015903091268862' />
     91  <node id='-1144' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.59842553932453' lon='9.015018390249102' />
     92  <node id='-1142' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60088902001335' lon='9.01940912864347' />
     93  <node id='-1140' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60326743500286' lon='9.016427358539831' />
     94  <node id='-1138' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.601887119002555' lon='9.01203662014546' />
     95  <node id='-1136' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60585641082779' lon='9.018722672540653' />
     96  <node id='-1134' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60596690162032' lon='9.015634813876297' />
     97  <node id='-1132' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.604301580971565' lon='9.015214706755497' />
     98  <node id='-1130' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60436654329301' lon='9.012866045750766' />
     99  <node id='-1128' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60423913401764' lon='9.018555164808395' />
     100  <node id='-1126' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60717742572599' lon='9.01872923792571' />
     101  <node id='-1124' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.60703277142605' lon='9.013572577815157'>
     102    <tag k='name' v='Overlapping from inside' />
     103  </node>
     104  <node id='-1122' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.635209934193504' lon='9.018326610645206' />
     105  <node id='-1120' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.6352269113224' lon='9.019663492186178' />
     106  <node id='-1118' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.637552722037306' lon='9.01966349218618' />
     107  <node id='-1116' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.63641529563854' lon='9.016911089013588' />
     108  <node id='-1114' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.636449249050045' lon='9.018300397281658' />
     109  <node id='-1112' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.6375696983495' lon='9.018300397281658' />
     110  <node id='-1110' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.63894475998399' lon='9.018300397281658' />
     111  <node id='-1108' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.63892778415116' lon='9.016727595468751'>
     112    <tag k='name' v='Adjacent areas' />
     113  </node>
     114  <node id='-1106' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.6092079239068' lon='8.979993067866946' />
     115  <node id='-1104' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60863583197044' lon='8.980463090593382' />
     116  <node id='-1102' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.609014473718254' lon='8.98002109059338' />
     117  <node id='-1100' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.609371911546816' lon='8.980231090593382' />
     118  <node id='-1098' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.608612034412964' lon='8.980057791204963' />
     119  <node id='-1096' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60921439656928' lon='8.980093090593378' />
     120  <node id='-1094' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.609030669493556' lon='8.979948937900476' />
     121  <node id='-1092' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.6089417745011' lon='8.980031090593382' />
     122  <node id='-1090' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60895389103724' lon='8.980141090593381' />
     123  <node id='-1088' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60860036701766' lon='8.979901130167272' />
     124  <node id='-1086' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.609068257011565' lon='8.980149604896077' />
     125  <node id='-1084' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60891754142889' lon='8.980011090593377' />
     126  <node id='-1082' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.608954900748586' lon='8.98016809059338' />
     127  <node id='-1080' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60876204588413' lon='8.97987409059338' />
     128  <node id='-1078' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60897770931492' lon='8.98016627430816' />
     129  <node id='-1076' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60896196872802' lon='8.980171090593378' />
     130  <node id='-1074' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.6087660847294' lon='8.979894090593382' />
     131  <node id='-1072' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60897812410956' lon='8.98013709059338' />
     132  <node id='-1070' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60897408526418' lon='8.98039109059338' />
     133  <node id='-1068' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60922498494282' lon='8.979824552607317' />
     134  <node id='-1066' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.608793346935066' lon='8.980332090593379' />
     135  <node id='-1064' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.608938745367084' lon='8.980394090593379' />
     136  <node id='-1062' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.609234546553864' lon='8.979989841865759' />
     137  <node id='-1060' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60879839549169' lon='8.980438090593381' />
     138  <node id='-1058' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60902961938861' lon='8.980286090593381' />
     139  <node id='-1056' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.60936383385557' lon='8.980073090593379'>
     140    <tag k='name' v='Part of outer way within bounds of outer shell, may get discarded' />
     141  </node>
     142  <node id='-1054' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true' lat='49.608932687099' lon='8.980308090593379' />
     143  <node id='-1052' action='modify' timestamp='2010-09-01T07:19:58Z' visible='true' lat='49.61927578427986' lon='9.010843113565025' />
     144  <node id='-1050' action='modify' timestamp='2010-09-01T07:19:58Z' visible='true' lat='49.61930744074704' lon='9.010363792085391' />
     145  <node id='-1048' action='modify' timestamp='2010-09-01T07:19:58Z' visible='true' lat='49.619308194472175' lon='9.010568550775721' />
     146  <node id='-1046' action='modify' timestamp='2010-09-01T07:19:58Z' visible='true' lat='49.61914709414676' lon='9.010694416849152' />
     147  <node id='-1044' action='modify' timestamp='2010-09-01T07:19:58Z' visible='true' lat='49.61921124616921' lon='9.010768452308135' />
     148  <node id='-1042' action='modify' timestamp='2010-09-01T07:19:58Z' visible='true' lat='49.6191016733426' lon='9.010641845079641' />
     149  <node id='-1040' action='modify' timestamp='2010-09-01T07:19:58Z' visible='true' lat='49.619436130456656' lon='9.010512488801263'>
     150    <tag k='name' v='Point very close to line, fails if integers used for intersetion testing' />
     151  </node>
     152  <node id='-1038' action='modify' timestamp='2010-09-01T07:19:58Z' visible='true' lat='49.61919862186357' lon='9.01044194354723' />
     153  <node id='-1036' action='modify' timestamp='2010-06-07T04:01:37Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61936490934421' lon='8.996259980085036' />
     154  <node id='-1034' action='modify' timestamp='2010-06-07T04:01:47Z' uid='213040' user='jf01' visible='true' version='1' lat='49.618977900492844' lon='8.995539558584047' />
     155  <node id='-1032' action='modify' timestamp='2010-06-07T04:01:44Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61891392865787' lon='8.995390158584048' />
     156  <node id='-1030' action='modify' timestamp='2010-06-07T04:01:43Z' uid='213040' user='jf01' visible='true' version='2' lat='49.618812565532245' lon='8.995051158584047' />
     157  <node id='-1028' action='modify' timestamp='2010-06-07T04:09:52Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61927947311732' lon='8.995179666802553' />
     158  <node id='-1026' action='modify' timestamp='2010-06-07T04:01:28Z' uid='213040' user='jf01' visible='true' version='2' lat='49.618452265063404' lon='8.995724652451486' />
     159  <node id='-1024' action='modify' timestamp='2010-06-07T04:01:19Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61919104075805' lon='8.995674458584046' />
     160  <node id='-1022' action='modify' timestamp='2010-06-07T04:01:21Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61920135559624' lon='8.996245458584049' />
     161  <node id='-1020' action='modify' timestamp='2010-06-07T04:01:48Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61911893607148' lon='8.996121758584048' />
     162  <node id='-1018' action='modify' timestamp='2010-06-07T04:01:51Z' uid='213040' user='jf01' visible='true' version='2' lat='49.619089213956855' lon='8.9954729834901' />
     163  <node id='-1016' action='modify' timestamp='2010-06-07T04:43:15Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61841795744353' lon='8.99538726378288' />
     164  <node id='-1014' action='modify' timestamp='2010-06-07T04:43:05Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61833584574924' lon='8.995436718912064' />
     165  <node id='-1012' action='modify' timestamp='2010-06-07T04:01:47Z' uid='213040' user='jf01' visible='true' version='1' lat='49.6188769340926' lon='8.996635058584047' />
     166  <node id='-1010' action='modify' timestamp='2010-06-07T04:01:27Z' uid='213040' user='jf01' visible='true' version='1' lat='49.618805424490084' lon='8.995240958584048' />
     167  <node id='-1008' action='modify' timestamp='2010-09-01T07:18:37Z' visible='true' version='1' lat='49.61860357699268' lon='8.995413148087703' />
     168  <node id='-1006' action='modify' timestamp='2010-06-07T04:19:51Z' uid='213040' user='jf01' visible='true' version='2' lat='49.619054567513054' lon='8.99570235858405' />
     169  <node id='-1004' action='modify' timestamp='2010-06-07T04:01:42Z' uid='213040' user='jf01' visible='true' version='2' lat='49.6192706109462' lon='8.995475082306038' />
     170  <node id='-1002' action='modify' timestamp='2010-09-01T07:18:37Z' visible='true' version='1' lat='49.61830307542173' lon='8.995566402351232' />
     171  <node id='-1000' action='modify' timestamp='2010-06-08T02:35:19Z' uid='213040' user='jf01' visible='true' version='3' lat='49.61833539405471' lon='8.99575962626546' />
     172  <node id='-998' action='modify' timestamp='2010-06-07T04:01:28Z' uid='213040' user='jf01' visible='true' version='1' lat='49.619103324713755' lon='8.996014188988203' />
     173  <node id='-996' action='modify' timestamp='2010-06-07T04:01:26Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61894050920333' lon='8.995383958584048' />
     174  <node id='-994' action='modify' timestamp='2010-06-07T04:01:34Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61940786119761' lon='8.996235487252036' />
     175  <node id='-992' action='modify' timestamp='2010-06-07T04:01:18Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61890073756624' lon='8.995328358584048' />
     176  <node id='-990' action='modify' timestamp='2010-06-07T04:09:47Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61876634712032' lon='8.995091558584049' />
     177  <node id='-988' action='modify' timestamp='2010-06-07T04:01:52Z' uid='213040' user='jf01' visible='true' version='2' lat='49.619270345959684' lon='8.995109191708606' />
     178  <node id='-986' action='modify' timestamp='2010-06-07T04:01:25Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61847981279682' lon='8.995689158584046' />
     179  <node id='-984' action='modify' timestamp='2010-06-07T04:01:48Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61917695703665' lon='8.996177458584047' />
     180  <node id='-982' action='modify' timestamp='2010-06-07T04:01:45Z' uid='213040' user='jf01' visible='true' version='2' lat='49.619147004333314' lon='8.99560795858405' />
     181  <node id='-980' action='modify' timestamp='2010-06-07T04:01:52Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61881673114018' lon='8.99613645858405' />
     182  <node id='-978' action='modify' timestamp='2010-06-07T04:01:42Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61911546473168' lon='8.995464758584049' />
     183  <node id='-976' action='modify' timestamp='2010-06-07T04:01:27Z' uid='213040' user='jf01' visible='true' version='2' lat='49.619266021696916' lon='8.995593958584049' />
     184  <node id='-974' action='modify' timestamp='2010-06-07T04:01:32Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61833207873726' lon='8.995450663782876' />
     185  <node id='-972' action='modify' timestamp='2010-06-07T04:01:44Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61893614523317' lon='8.99656535858405' />
     186  <node id='-970' action='modify' timestamp='2010-06-07T04:01:30Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61884954010229' lon='8.99544388066912' />
     187  <node id='-968' action='modify' timestamp='2010-06-07T04:01:38Z' uid='213040' user='jf01' visible='true' version='2' lat='49.619040087066864' lon='8.995677958584048' />
     188  <node id='-966' action='modify' timestamp='2010-09-01T07:18:37Z' visible='true' version='1' lat='49.618649600482655' lon='8.995357966858563' />
     189  <node id='-964' action='modify' timestamp='2010-06-07T04:01:37Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61923234496662' lon='8.99544370009753' />
     190  <node id='-962' action='modify' timestamp='2010-06-07T04:01:50Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61832615179851' lon='8.995697202066708' />
     191  <node id='-960' action='modify' timestamp='2010-06-07T04:01:19Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61834700924229' lon='8.995830458584047' />
     192  <node id='-958' action='modify' timestamp='2010-06-07T04:19:45Z' uid='213040' user='jf01' visible='true' version='1' lat='49.619121713143315' lon='8.995923658584049' />
     193  <node id='-956' action='modify' timestamp='2010-06-08T02:40:40Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61939929556202' lon='8.996194339974096' />
     194  <node id='-954' action='modify' timestamp='2010-06-07T04:19:50Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61912082051308' lon='8.995806758584049' />
     195  <node id='-952' action='modify' timestamp='2010-06-07T04:01:23Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61892979764025' lon='8.995314558584049' />
     196  <node id='-950' action='modify' timestamp='2010-06-07T04:09:42Z' uid='213040' user='jf01' visible='true' version='1' lat='49.618729848460106' lon='8.995120458584049' />
     197  <node id='-948' action='modify' timestamp='2010-06-07T04:01:32Z' uid='213040' user='jf01' visible='true' version='1' lat='49.619263244625124' lon='8.994923858584047' />
     198  <node id='-946' action='modify' timestamp='2010-06-07T04:01:29Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61852011761496' lon='8.995698010732623' />
     199  <node id='-944' action='modify' timestamp='2010-06-07T04:19:49Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61911060485593' lon='8.995633158584049' />
     200  <node id='-942' action='modify' timestamp='2010-06-07T04:01:45Z' uid='213040' user='jf01' visible='true' version='2' lat='49.618550073320144' lon='8.995780621162336' />
     201  <node id='-940' action='modify' timestamp='2010-06-07T04:19:45Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61912320086037' lon='8.995462358584048' />
     202  <node id='-938' action='modify' timestamp='2010-06-07T04:01:38Z' uid='213040' user='jf01' visible='true' version='1' lat='49.618741651016016' lon='8.995973558584048' />
     203  <node id='-936' action='modify' timestamp='2010-06-07T04:01:27Z' uid='213040' user='jf01' visible='true' version='1' lat='49.619291213705324' lon='8.995639958584048' />
     204  <node id='-934' action='modify' timestamp='2010-06-07T04:01:30Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61827668045692' lon='8.99546050345486' />
     205  <node id='-932' action='modify' timestamp='2010-06-07T04:01:40Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61903750835727' lon='8.996497858584048' />
     206  <node id='-930' action='modify' timestamp='2010-06-07T04:01:34Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61893108699506' lon='8.995823458584047' />
     207  <node id='-928' action='modify' timestamp='2010-06-07T04:01:22Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61871526883218' lon='8.995280358584047' />
     208  <node id='-926' action='modify' timestamp='2010-06-07T04:19:51Z' uid='213040' user='jf01' visible='true' version='2' lat='49.618992876844864' lon='8.99570235858405' />
     209  <node id='-924' action='modify' timestamp='2008-01-02T17:01:25Z' uid='5748' user='fatbozz' visible='true' version='2' lat='49.61895637818563' lon='8.995086758584048' />
     210  <node id='-922' action='modify' timestamp='2010-06-07T04:01:34Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61926267645462' lon='8.99538470439111' />
     211  <node id='-920' action='modify' timestamp='2010-06-07T04:01:46Z' uid='213040' user='jf01' visible='true' version='2' lat='49.618898258037724' lon='8.99500935858405' />
     212  <node id='-918' action='modify' timestamp='2010-06-07T04:01:20Z' uid='213040' user='jf01' visible='true' version='2' lat='49.6193022153382' lon='8.995326033677996' />
     213  <node id='-916' action='modify' timestamp='2010-06-08T02:47:58Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61839620309099' lon='8.995796258584049' />
     214  <node id='-914' action='modify' timestamp='2010-06-07T04:19:52Z' uid='213040' user='jf01' visible='true' version='2' lat='49.619151070759926' lon='8.995857358584047' />
     215  <node id='-912' action='modify' timestamp='2010-06-07T04:01:24Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61938870876071' lon='8.99615419927907' />
     216  <node id='-910' action='modify' timestamp='2010-06-07T04:19:47Z' uid='213040' user='jf01' visible='true' version='1' lat='49.619181023463256' lon='8.995726458584048' />
     217  <node id='-908' action='modify' timestamp='2010-06-07T04:01:24Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61892166478678' lon='8.995283158584046' />
     218  <node id='-906' action='modify' timestamp='2010-06-07T04:01:41Z' uid='213040' user='jf01' visible='true' version='2' lat='49.618588019425566' lon='8.995251458584047' />
     219  <node id='-904' action='modify' timestamp='2010-06-07T04:02:03Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61916932008913' lon='8.995049658584046' />
     220  <node id='-902' action='modify' timestamp='2010-06-07T04:01:25Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61853988130028' lon='8.995741971475498' />
     221  <node id='-900' action='modify' timestamp='2010-06-07T04:01:19Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61856213314697' lon='8.995770558584049' />
     222  <node id='-898' action='modify' timestamp='2010-06-07T04:01:51Z' uid='213040' user='jf01' visible='true' version='2' lat='49.6191149254759' lon='8.995659844328351' />
     223  <node id='-896' action='modify' timestamp='2010-06-07T04:01:36Z' uid='213040' user='jf01' visible='true' version='1' lat='49.618532378803636' lon='8.995501158584048' />
     224  <node id='-894' action='modify' timestamp='2010-06-07T04:01:21Z' uid='213040' user='jf01' visible='true' version='2' lat='49.6190895756353' lon='8.995710845912319' />
     225  <node id='-892' action='modify' timestamp='2010-06-07T04:01:35Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61934179608414' lon='8.995588458584047' />
     226  <node id='-890' action='modify' timestamp='2010-06-08T02:34:42Z' uid='213040' user='jf01' visible='true' version='2' lat='49.618287025229776' lon='8.995497915492605' />
     227  <node id='-888' action='modify' timestamp='2010-06-07T04:01:24Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61894606334714' lon='8.995811658584048' />
     228  <node id='-886' action='modify' timestamp='2010-06-07T04:01:35Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61914254118215' lon='8.996324358584049' />
     229  <node id='-884' action='modify' timestamp='2010-06-07T04:01:42Z' uid='213040' user='jf01' visible='true' version='1' lat='49.619252929787' lon='8.996340858584047' />
     230  <node id='-882' action='modify' timestamp='2010-06-07T04:19:52Z' uid='213040' user='jf01' visible='true' version='3' lat='49.61895548555539' lon='8.995552858584048' />
     231  <node id='-880' action='modify' timestamp='2010-06-07T04:01:49Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61890252842708' lon='8.995086054646046' />
     232  <node id='-878' action='modify' timestamp='2010-06-07T04:01:31Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61925590522109' lon='8.995350358584048' />
     233  <node id='-876' action='modify' timestamp='2010-06-07T04:43:09Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61884529530876' lon='8.995041258584049' />
     234  <node id='-874' action='modify' timestamp='2010-06-07T04:09:41Z' uid='213040' user='jf01' visible='true' version='2' lat='49.619293496479635' lon='8.995280333552733' />
     235  <node id='-872' action='modify' timestamp='2010-06-08T02:48:00Z' uid='213040' user='jf01' visible='true' version='2' lat='49.618441330512404' lon='8.995765258584047' />
     236  <node id='-870' action='modify' timestamp='2010-06-07T04:01:32Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61937056422288' lon='8.996163025302147' />
     237  <node id='-868' action='modify' timestamp='2010-06-07T04:19:46Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61917110534958' lon='8.995703458584048' />
     238  <node id='-866' action='modify' timestamp='2010-06-07T04:01:38Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61903016895301' lon='8.995231258584047' />
     239  <node id='-864' action='modify' timestamp='2010-06-07T04:01:37Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61859496210561' lon='8.995280458584048' />
     240  <node id='-862' action='modify' timestamp='2010-06-07T04:43:01Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61836068594718' lon='8.995422220691438' />
     241  <node id='-860' action='modify' timestamp='2010-06-08T02:49:37Z' uid='213040' user='jf01' visible='true' version='1' lat='49.6188339886587' lon='8.996517858584049' />
     242  <node id='-858' action='modify' timestamp='2010-06-07T04:01:53Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61910723269727' lon='8.99568665858405' />
     243  <node id='-856' action='modify' timestamp='2010-06-07T04:01:20Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61858740669941' lon='8.995430488236533' />
     244  <node id='-854' action='modify' timestamp='2010-06-07T04:01:24Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61906924632146' lon='8.995714758584047' />
     245  <node id='-852' action='modify' timestamp='2010-06-07T04:01:31Z' uid='213040' user='jf01' visible='true' version='2' lat='49.6193399116426' lon='8.995502758584049' />
     246  <node id='-850' action='modify' timestamp='2010-06-07T04:01:18Z' uid='213040' user='jf01' visible='true' version='2' lat='49.61829424299725' lon='8.99553268621828' />
     247  <node id='-848' action='modify' timestamp='2010-06-07T04:01:46Z' uid='213040' user='jf01' visible='true' version='1' lat='49.61923120911822' lon='8.996295158584047' />
     248  <node id='-846' action='modify' timestamp='2010-06-07T04:01:23Z' uid='213040' user='jf01' visible='true' version='1' lat='49.619005572030616' lon='8.996005058584048' />
     249  <node id='-844' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.61026681070658' lon='9.02106461753563' />
     250  <node id='-842' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.61022835848153' lon='8.975691709364362' />
     251  <node id='-840' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61410362729504' lon='8.98496099667205' />
     252  <node id='-838' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.614062864506266' lon='8.983912462130109' />
     253  <node id='-836' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61138603341918' lon='8.988798633095548' />
     254  <node id='-834' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61449346139858' lon='8.986457183763283' />
     255  <node id='-832' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61511052965412' lon='8.984688429055172' />
     256  <node id='-830' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61553009112371' lon='8.983970131529919' />
     257  <node id='-828' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61460700246505' lon='8.988431973672913' />
     258  <node id='-826' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.6182425713161' lon='8.98839101529237' />
     259  <node id='-824' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61158157785009' lon='8.979216338050403' />
     260  <node id='-822' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61142233977348' lon='8.983148342582673' />
     261  <node id='-820' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61333316235859' lon='8.983025467441038' />
     262  <node id='-818' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.613959471238125' lon='8.98192122950156' />
     263  <node id='-816' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.614686616366264' lon='8.983148342582673' />
     264  <node id='-814' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61537659806236' lon='8.981591924121982' />
     265  <node id='-812' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.616544237141035' lon='8.982902592299407' />
     266  <node id='-810' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61813642716417' lon='8.982902592299407' />
     267  <node id='-808' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.61808335500149' lon='8.979625921855847'>
     268    <tag k='name' v='Inner touchin aras, should create three inner parts' />
     269  </node>
     270  <node id='-806' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.61981906150899' lon='9.02065420386435' />
     271  <node id='-804' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.619780616819725' lon='8.976919630914859' />
     272  <node id='-802' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62577739053262' lon='9.016088937412146' />
     273  <node id='-800' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.623654791826745' lon='9.016047979031603' />
     274  <node id='-798' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62131982643976' lon='9.017891106156107' />
     275  <node id='-796' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62691824912582' lon='9.018259731581004' />
     276  <node id='-794' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62089527525643' lon='9.011460640410618' />
     277  <node id='-792' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62121368899072' lon='9.014983061137446' />
     278  <node id='-790' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.622832259967964' lon='9.015064977898536' />
     279  <node id='-788' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62360172567424' lon='9.013549517818388' />
     280  <node id='-786' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62479570012563' lon='9.015310728181802' />
     281  <node id='-784' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.625591666837664' lon='9.013180892393487' />
     282  <node id='-782' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62681212387209' lon='9.014245810287644' />
     283  <node id='-780' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62673252978008' lon='9.011501598791163'>
     284    <tag k='name' v='Touching areas, should not be combined where only touching' />
     285  </node>
     286  <node id='-778' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.622089316031165' lon='9.00208117126593' />
     287  <node id='-776' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62251385681077' lon='9.004866341142955' />
     288  <node id='-774' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62468957024812' lon='9.0049072995235' />
     289  <node id='-772' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.6245303749984' lon='9.001139128513406' />
     290  <node id='-770' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62628149413567' lon='9.002204046407563' />
     291  <node id='-768' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.626201899176685' lon='8.996838498556237'>
     292    <tag k='name' v='Two touching areas, should NOT be combined into one' />
     293  </node>
     294  <node id='-766' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.623230260988386' lon='8.996387956370246' />
     295  <node id='-764' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.623413552631625' lon='8.988000110097728' />
     296  <node id='-762' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62485693695976' lon='8.99075251327032' />
     297  <node id='-760' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62551493621301' lon='8.98813117691547' />
     298  <node id='-758' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62216116981817' lon='8.980955268644076' />
     299  <node id='-756' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.627255407522924' lon='8.988884811117488' />
     300  <node id='-754' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62498429234751' lon='8.99252191530984' />
     301  <node id='-752' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.62213994271339' lon='8.988098410211036' />
     302  <node id='-750' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true' lat='49.626279053225524' lon='8.981414002506174'>
     303    <tag k='name' v='Self-intersecting area' />
     304  </node>
     305  <node id='-748' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.634297623749426' lon='9.009913613166118'>
     306    <tag k='name' v='two nodes are overlapping, but not identical' />
     307  </node>
     308  <node id='-746' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.633945117271765' lon='9.010801740085483' />
     309  <node id='-744' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63393264307744' lon='9.011047179395488' />
     310  <node id='-742' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63397651971739' lon='9.010999225285477' />
     311  <node id='-740' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.633945127068216' lon='9.010800819035481' />
     312  <node id='-738' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6339459893696' lon='9.010719537165489' />
     313  <node id='-736' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6339376312857' lon='9.010915330605481' />
     314  <node id='-734' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63365009319664' lon='9.01041866293549' />
     315  <node id='-732' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63394377111033' lon='9.010928613485484' />
     316  <node id='-730' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.633856212166755' lon='9.010893473725478' />
     317  <node id='-728' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63389375219822' lon='9.010963515015485' />
     318  <node id='-726' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63394262769327' lon='9.011036375275484' />
     319  <node id='-724' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63376409638575' lon='9.010301073275484' />
     320  <node id='-722' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63397051736248' lon='9.010775661985484' />
     321  <node id='-720' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.633942630142286' lon='9.011036145015492' />
     322  <node id='-718' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.632576330191526' lon='9.001884781637644' />
     323  <node id='-716' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63246699537921' lon='8.999116354145995' />
     324  <node id='-714' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.629711140902785' lon='8.999277013032064' />
     325  <node id='-712' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.631610067691966' lon='9.003079417313643' />
     326  <node id='-710' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6315080216117' lon='8.997138044228079' />
     327  <node id='-708' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.633374730988635' lon='9.000934610919133' />
     328  <node id='-706' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.62793647221095' lon='9.020860514336768' />
     329  <node id='-704' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.62789803392637' lon='8.977125941387275' />
     330  <node id='-702' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6347537242248' lon='9.020943924631984' />
     331  <node id='-700' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.634715291319765' lon='8.977209351682495' />
     332  <node id='-698' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.633235031946306' lon='8.989050437839317' />
     333  <node id='-696' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.62984284307208' lon='8.984760326211225' />
     334  <node id='-694' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.629734577834874' lon='8.988799717029881' />
     335  <node id='-692' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63204418403885' lon='8.988131128204722' />
     336  <node id='-690' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63146679275468' lon='8.988019696733868' />
     337  <node id='-688' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.633361332289276' lon='8.984899615549795' />
     338  <node id='-686' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.629896975600474' lon='8.982336691720024' />
     339  <node id='-684' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63282112167936' lon='8.984873752905482' />
     340  <node id='-682' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63191788028032' lon='8.988911148500739' />
     341  <node id='-680' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.632224617411495' lon='8.98487175768208' />
     342  <node id='-678' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63087135082409' lon='8.987936123130721' />
     343  <node id='-676' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.631033744799794' lon='8.984788184078935' />
     344  <node id='-674' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63332524651039' lon='8.982503838926318' />
     345  <node id='-672' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63276591351912' lon='8.988186843940152' />
     346  <node id='-670' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.631502879910435' lon='8.984843899814363' />
     347  <node id='-668' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.638457370514' lon='9.015664984322639' />
     348  <node id='-666' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64179212326588' lon='9.014488850844076' />
     349  <node id='-664' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63993662729721' lon='9.01494551470347' />
     350  <node id='-662' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64173715249402' lon='9.01288893804428' />
     351  <node id='-660' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.636497278618506' lon='9.01558299248487' />
     352  <node id='-658' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63614569649766' lon='9.016254920813461' />
     353  <node id='-656' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.639285639926086' lon='9.016386267202325' />
     354  <node id='-654' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63846974351432' lon='9.014959728094702' />
     355  <node id='-652' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6362341674196' lon='9.011212347946481' />
     356  <node id='-650' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63932787364639' lon='9.011341760369241' />
     357  <node id='-648' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.639297465489946' lon='9.013075043737933' />
     358  <node id='-646' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.638495992538296' lon='9.013041516659012' />
     359  <node id='-644' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63656290879177' lon='9.01184224653937' />
     360  <node id='-642' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63931004998166' lon='9.014994879645652' />
     361  <node id='-640' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63851559945754' lon='9.011923928883068' />
     362  <node id='-638' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63989778320692' lon='9.01301762121565' />
     363  <node id='-636' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63994510769946' lon='9.011537754906723' />
     364  <node id='-634' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.641650361020126' lon='9.011375542032631' />
     365  <node id='-632' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.640355464550595' lon='9.00163017923136' />
     366  <node id='-630' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.640963432528' lon='9.002300773285747' />
     367  <node id='-628' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63983876223289' lon='8.999763400318008' />
     368  <node id='-626' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.640355464550595' lon='9.000557228744347' />
     369  <node id='-624' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.641505032635514' lon='9.005561427326938' />
     370  <node id='-622' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.639702839791006' lon='9.002946110514843' />
     371  <node id='-620' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.641397690721426' lon='9.002032535663991' />
     372  <node id='-618' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64135304304343' lon='9.008042625328157' />
     373  <node id='-616' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.636803870494575' lon='9.005634441607576' />
     374  <node id='-614' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63766439678692' lon='9.008322826347838' />
     375  <node id='-612' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.638889008438305' lon='9.003170088929009' />
     376  <node id='-610' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63655427055324' lon='9.003685105162774' />
     377  <node id='-608' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63919649619353' lon='9.000021094269913' />
     378  <node id='-606' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64153777547409' lon='8.98052084180162' />
     379  <node id='-604' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.639336573937996' lon='8.985619502515908' />
     380  <node id='-602' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63671001008765' lon='8.985696754950974' />
     381  <node id='-600' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64158780162527' lon='8.984460715989934' />
     382  <node id='-598' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63665997892509' lon='8.979825569886037' />
     383  <node id='-596' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63635979087037' lon='8.9920314546263' />
     384  <node id='-594' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64038715981111' lon='8.984846978165258' />
     385  <node id='-592' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64166284075567' lon='8.990370527272402' />
     386  <node id='-590' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63672921217317' lon='9.001496060420484' />
     387  <node id='-588' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.636707497273726' lon='8.996902491147958' />
     388  <node id='-586' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63866179944343' lon='9.001060174285136' />
     389  <node id='-584' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63833608786159' lon='9.001965476258553' />
     390  <node id='-582' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63831098015055' lon='8.986005764691233' />
     391  <node id='-580' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63620969614912' lon='8.984267584902272' />
     392  <node id='-578' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64113713627012' lon='8.99764014460778' />
     393  <node id='-576' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.63766059241029' lon='8.985426371428245' />
     394  <node id='-574' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64222947566583' lon='8.976745109963648' />
     395  <node id='-572' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64226790264086' lon='9.020479682913138' />
     396  <node id='-570' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6687778596993' lon='9.028553906352727' />
     397  <node id='-568' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66476023970688' lon='9.029688590118962' />
     398  <node id='-566' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64560080131112' lon='8.988407502515859' />
     399  <node id='-564' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64619224514668' lon='8.984061673983168' />
     400  <node id='-562' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.664846643627826' lon='9.02334771024883' />
     401  <node id='-560' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66903704959538' lon='9.022880487521558' />
     402  <node id='-558' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.671931242953896' lon='9.026017554404675' />
     403  <node id='-556' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66722269132057' lon='9.026351284924155' />
     404  <node id='-554' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64305580574678' lon='8.992869020494213' />
     405  <node id='-552' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6465677851024' lon='8.992596999330347' />
     406  <node id='-550' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64654691824636' lon='8.982418392157395' />
     407  <node id='-548' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64294039575888' lon='8.98264180269116' />
     408  <node id='-546' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66726589111355' lon='9.018808975183893' />
     409  <node id='-544' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.67180165588925' lon='9.019276197911166'>
     410    <tag k='name' v='out of bounds' />
     411  </node>
     412  <node id='-542' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64660348405886' lon='9.007804150387257' />
     413  <node id='-540' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.645064815871' lon='8.999528632035787' />
     414  <node id='-538' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.643583272941804' lon='8.996426078862356' />
     415  <node id='-536' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64390917555046' lon='9.00236900726505' />
     416  <node id='-534' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.645549394972946' lon='8.997512960693886' />
     417  <node id='-532' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64620102922634' lon='8.995285052653605' />
     418  <node id='-530' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.644533441390884' lon='9.001738472218983' />
     419  <node id='-528' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.645870282835396' lon='9.000573288940334' />
     420  <node id='-526' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64561767902291' lon='8.987111582364214' />
     421  <node id='-524' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64624752120218' lon='8.990209078516749' />
     422  <node id='-522' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6438359138228' lon='8.988873075900425' />
     423  <node id='-520' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64362715512701' lon='8.983795590458412' />
     424  <node id='-518' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64400653203681' lon='8.985527741087623' />
     425  <node id='-516' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64512070290696' lon='8.990191229749867' />
     426  <node id='-514' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64509437228782' lon='8.985632145182455' />
     427  <node id='-512' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.644215448513066' lon='8.987601210318644' />
     428  <node id='-510' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6440995060445' lon='9.012176810003897' />
     429  <node id='-508' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64364363066422' lon='9.010830064185653' />
     430  <node id='-506' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64333102750582' lon='9.015932402078883' />
     431  <node id='-504' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6436516438452' lon='9.013337536747516' />
     432  <node id='-502' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64477854294109' lon='9.010865000644996' />
     433  <node id='-500' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64566131406722' lon='9.01503858959705' />
     434  <node id='-498' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.646452701397266' lon='9.00974135512665'>
     435    <tag k='name' v='Both part of other relations' />
     436  </node>
     437  <node id='-496' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.645694403782294' lon='9.012131348650524' />
     438  <node id='-494' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.643570600890634' lon='9.005424239693767' />
     439  <node id='-492' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64579713321828' lon='9.001725329495672' />
     440  <node id='-490' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.645108516691536' lon='9.00501200093294' />
     441  <node id='-488' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.644279396738646' lon='8.99701844322583' />
     442  <node id='-486' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64446300005248' lon='9.017591884759854' />
     443  <node id='-484' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.646377327053195' lon='9.017591884759854' />
     444  <node id='-482' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64634787643868' lon='9.01859251804108' />
     445  <node id='-480' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64442618533402' lon='9.018507236795525' />
     446  <node id='-478' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65350134232707' lon='9.010218218565463'>
     447    <tag k='name' v='One Area already part of multipolygon (as inner)' />
     448  </node>
     449  <node id='-476' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.651543995109876' lon='9.011086020347133' />
     450  <node id='-474' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64702795382207' lon='9.021373906176958' />
     451  <node id='-472' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64698953060391' lon='8.97763933322747' />
     452  <node id='-470' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6440995060445' lon='9.015089670434026' />
     453  <node id='-468' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64633804682556' lon='9.016044421132413' />
     454  <node id='-466' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64329477394559' lon='9.00982115694612' />
     455  <node id='-464' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64474487637503' lon='9.013313148784425' />
     456  <node id='-462' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.649036528490285' lon='9.01626713010843' />
     457  <node id='-460' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.651484566652904' lon='9.01400037262895' />
     458  <node id='-458' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.653441916259965' lon='9.016322294998254' />
     459  <node id='-456' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65267321841768' lon='9.012636639171191' />
     460  <node id='-454' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.652640133446276' lon='9.015498396786755' />
     461  <node id='-452' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64972521590133' lon='9.013842827268181' />
     462  <node id='-450' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64907390166997' lon='9.010241166221228' />
     463  <node id='-448' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.649790825127035' lon='9.010994229724082' />
     464  <node id='-446' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65649630973553' lon='9.01456121513066' />
     465  <node id='-444' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.655114612313845' lon='9.01024820290498' />
     466  <node id='-442' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65777838791238' lon='9.0156778202983' />
     467  <node id='-440' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.659983770585875' lon='9.015660786026782' />
     468  <node id='-438' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.659950690584154' lon='9.018522543642344' />
     469  <node id='-436' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6577783879124' lon='9.01859068072843' />
     470  <node id='-434' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.650467504431084' lon='9.012653673442712' />
     471  <node id='-432' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.650467504431084' lon='9.01556653387284' />
     472  <node id='-430' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66467233731082' lon='9.018729539100242' />
     473  <node id='-428' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66572689580407' lon='9.018683643788718' />
     474  <node id='-426' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65948208481168' lon='9.016329331682007' />
     475  <node id='-424' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65954150350348' lon='9.010225255249217'>
     476    <tag k='name' v='One Area already part of multipolygon (as outer)' />
     477  </node>
     478  <node id='-422' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65831483593041' lon='9.011804408209608' />
     479  <node id='-420' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65507724377221' lon='9.016274166792183' />
     480  <node id='-418' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65825541574074' lon='9.014718760491427' />
     481  <node id='-416' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.656561909834345' lon='9.011712617586559' />
     482  <node id='-414' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.663989090028004' lon='9.01179934706001' />
     483  <node id='-412' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.663929676767346' lon='9.01471369934183' />
     484  <node id='-410' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66210268358402' lon='9.017513313344837' />
     485  <node id='-408' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.662236368338334' lon='9.011707556436962' />
     486  <node id='-406' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.665266457583265' lon='9.016733093048918' />
     487  <node id='-404' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6657566013461' lon='9.017559208656362' />
     488  <node id='-402' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66156794089354' lon='9.014644856374543' />
     489  <node id='-400' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66149367061061' lon='9.016824883671967' />
     490  <node id='-398' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.582683357701704' lon='9.00815487768719' />
     491  <node id='-396' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.654142227092336' lon='8.97793106762297' />
     492  <node id='-394' action='modify' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.58144205087815' lon='8.993437879659092' />
     493  <node id='-392' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66770174614116' lon='9.008788568211484' />
     494  <node id='-390' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66089950426598' lon='9.010651964271892' />
     495  <node id='-388' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66084008723247' lon='9.01744447037755' />
     496  <node id='-386' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65418064466472' lon='9.02166564057246' />
     497  <node id='-384' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.665325869211465' lon='9.010629016616129'>
     498    <tag k='name' v='Member of some (i.e. not multigon) relation' />
     499  </node>
     500  <node id='-382' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66824309940781' lon='8.99379608098765' />
     501  <node id='-380' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66019710027813' lon='9.021519330497165' />
     502  <node id='-378' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.660221488976575' lon='8.977137289660517' />
     503  <node id='-376' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65700948686801' lon='8.988227465960346' />
     504  <node id='-374' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65806085263415' lon='8.990794583824783' />
     505  <node id='-372' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65697557146509' lon='8.992313898479246' />
     506  <node id='-370' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65931567881406' lon='8.992156727997747' />
     507  <node id='-368' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65823042563044' lon='8.988227465960346' />
     508  <node id='-366' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65700948686801' lon='8.986970102108378' />
     509  <node id='-364' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65931567881406' lon='8.986865321787379'>
     510    <tag k='name' v='SOME Intersection already have nodes added' />
     511  </node>
     512  <node id='-362' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65558501959522' lon='8.988437026602341' />
     513  <node id='-360' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65545132661812' lon='8.981025288893223' />
     514  <node id='-358' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65701145955204' lon='8.98306850515267' />
     515  <node id='-356' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65792716645855' lon='8.983382846115664' />
     516  <node id='-354' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65809673992071' lon='8.980815728251226' />
     517  <node id='-352' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65687579780412' lon='8.980815728251226' />
     518  <node id='-350' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65918199608578' lon='8.984744990288629' />
     519  <node id='-348' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65684188230803' lon='8.984902160770126' />
     520  <node id='-346' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65687579780412' lon='8.979558364399258' />
     521  <node id='-344' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65918199608578' lon='8.97945358407826'>
     522    <tag k='name' v='Intersection already have nodes added' />
     523  </node>
     524  <node id='-342' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.653656418352305' lon='8.980925219001294' />
     525  <node id='-340' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65083240952062' lon='8.981009751040055' />
     526  <node id='-338' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65093842995153' lon='8.98362536207706' />
     527  <node id='-336' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65366266054767' lon='8.983765181752341' />
     528  <node id='-334' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66327697326473' lon='8.996037451903568' />
     529  <node id='-332' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66163205844883' lon='8.996182583343169' />
     530  <node id='-330' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66336086872286' lon='9.000172520579218' />
     531  <node id='-328' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66439890567706' lon='9.000253362850133' />
     532  <node id='-326' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64910487989931' lon='8.98434746261959' />
     533  <node id='-324' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.661575265881794' lon='9.002417415068946' />
     534  <node id='-322' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66111564855195' lon='8.994837077867599' />
     535  <node id='-320' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.664258008517386' lon='8.994834196254615' />
     536  <node id='-318' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65154365880048' lon='8.989894759403137' />
     537  <node id='-316' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65180728142213' lon='8.98635078159476' />
     538  <node id='-314' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65263419499493' lon='8.992015874465995' />
     539  <node id='-312' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64821655131596' lon='8.986618619738293' />
     540  <node id='-310' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65267519581664' lon='8.982531354736969'>
     541    <tag k='name' v='Joining an two areas with self-overlap' />
     542  </node>
     543  <node id='-308' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64837612802103' lon='8.982669694368326' />
     544  <node id='-306' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6498411096278' lon='8.989584718400737' />
     545  <node id='-304' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.648702988205066' lon='8.99108732452821' />
     546  <node id='-302' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64965980248303' lon='8.997301325111557' />
     547  <node id='-300' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.6534782364111' lon='9.003730452396017' />
     548  <node id='-298' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.650123242376026' lon='8.984223634986959' />
     549  <node id='-296' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64862774189198' lon='8.99756699152827' />
     550  <node id='-294' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.647526853143034' lon='8.99921412331189' />
     551  <node id='-292' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64965980248303' lon='9.003039719712563' />
     552  <node id='-290' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.648042897844014' lon='9.003942985529385' />
     553  <node id='-288' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65151745640557' lon='8.997992057795011' />
     554  <node id='-286' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.659323888301465' lon='9.00052935158495' />
     555  <node id='-284' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65131105391522' lon='9.00298658642922' />
     556  <node id='-282' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.657294551336726' lon='9.005523880219158' />
     557  <node id='-280' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.64759565941927' lon='8.995601060044594' />
     558  <node id='-278' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.652897713964435' lon='8.995398194580462'>
     559    <tag k='name' v='Overlapping Itself' />
     560  </node>
     561  <node id='-276' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66298227683501' lon='9.007574342263663' />
     562  <node id='-274' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65595437351232' lon='9.002670090930014' />
     563  <node id='-272' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.664767306664714' lon='9.00358600531296' />
     564  <node id='-270' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.656334599426415' lon='8.99596685442522' />
     565  <node id='-268' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65622420968986' lon='8.999630518959972' />
     566  <node id='-266' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65482452933729' lon='8.99800181533644' />
     567  <node id='-264' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.658215448844345' lon='8.998101909487305' />
     568  <node id='-262' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65470614469758' lon='9.000967096568774' />
     569  <node id='-260' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.65966007592634' lon='8.995756927212474'>
     570    <tag k='name' v='With Inner Nodes, resolve tag conflicts beforehand' />
     571  </node>
     572  <node id='-258' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66102960777179' lon='9.004102187558955' />
     573  <node id='-256' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.658143795735675' lon='9.001321365825214' />
     574  <node id='-254' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.659381328509475' lon='9.002998050852923' />
     575  <node id='-252' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66356462957665' lon='9.003786018319271' />
     576  <node id='-250' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.663673852556485' lon='9.001872836660935' />
     577  <node id='-248' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66509579743186' lon='9.006492938770437' />
     578  <node id='-246' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66247822670222' lon='9.006405902938653' />
     579  <node id='-244' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66260897027721' lon='8.996995205661822' />
     580  <node id='-242' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.665246272951265' lon='8.996673744036638'>
     581    <tag k='name' v='No Additional Inner Nodes' />
     582  </node>
     583  <node id='-240' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66122094281029' lon='8.987593944961972' />
     584  <node id='-238' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66423062929877' lon='8.985896954118042' />
     585  <node id='-236' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66193599760082' lon='8.983668051096597' />
     586  <node id='-234' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66414787714609' lon='8.98167662069808' />
     587  <node id='-232' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.661140812390876' lon='8.980754551545285' />
     588  <node id='-230' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66550322539429' lon='8.987481709734286' />
     589  <node id='-228' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66309431357888' lon='8.98771163350794' />
     590  <node id='-226' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.66293444373006' lon='8.979904268383734' />
     591  <node id='-224' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.665557350679464' lon='8.980018030697323'>
     592    <tag k='name' v='Multipolygon' />
     593  </node>
     594  <node id='-222' timestamp='2010-09-01T07:08:32Z' visible='true' lat='49.632576330191526' lon='9.001884781637644' />
     595  <node id='-220' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60631884924948' lon='8.99828651422655' />
     596  <node id='-218' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60878668733591' lon='8.998823363912022'>
     597    <tag k='name' v='Tricky islands' />
     598  </node>
     599  <node id='-216' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.608699717192344' lon='9.003504022107236' />
     600  <node id='-214' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60285061894932' lon='9.002598088263003' />
     601  <node id='-212' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60288323668442' lon='9.00095398610124' />
     602  <node id='-210' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60774303537242' lon='9.001792813734793' />
     603  <node id='-208' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60822137862924' lon='8.999662191545573' />
     604  <node id='-206' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60492723788813' lon='8.998991129438732' />
     605  <node id='-204' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60676459136411' lon='8.999142118412772' />
     606  <node id='-202' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60578612771775' lon='8.996189445142672' />
     607  <node id='-200' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60523165626767' lon='9.002363216525607' />
     608  <node id='-198' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.604090077543404' lon='9.004544168372842' />
     609  <node id='-196' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.605068575229296' lon='8.993991716742768' />
     610  <node id='-194' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60618838737178' lon='8.994377577454202' />
     611  <node id='-192' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.60780984108299' lon='8.997889316593701' />
     612  <node id='-180' action='modify' timestamp='2010-09-01T07:34:34Z' visible='true' lat='49.59410169848016' lon='9.001948669267644' />
     613  <node id='-170' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.5953418202474' lon='8.999475001790184'>
     614    <tag k='name' v='Illegal multipolygon - convert to single polygon' />
     615  </node>
     616  <node id='-156' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.590607739738225' lon='9.005271937488764' />
     617  <node id='-146' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.589308021229364' lon='9.000654170391176' />
     618  <node id='-140' action='modify' timestamp='2010-09-01T07:34:34Z' visible='true' lat='49.59190240292961' lon='9.00051199489379' />
     619  <node id='-134' action='modify' timestamp='2010-08-22T07:13:40Z' visible='true' lat='49.596813390158815' lon='9.009579167802686'>
     620    <tag k='name' v='Insane self-overlapping test. Should result in may small polygons no multipolygon' />
     621  </node>
     622  <node id='-132' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.590630159502766' lon='9.002078403822205' />
     623  <node id='-128' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.5878107930004' lon='9.00095637433437' />
     624  <node id='-116' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.59395593568672' lon='8.999308852106346' />
     625  <node id='-104' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.59063794877312' lon='8.998628118047407' />
     626  <node id='-100' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.592907759510084' lon='8.995386920867338' />
     627  <node id='-78' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true' lat='49.59299360654739' lon='8.999428858917476' />
     628  <node id='-18' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.590479254891314' lon='8.99053115169711' />
     629  <node id='-16' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.58612382692311' lon='8.990374907874841' />
     630  <node id='-14' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.58663029201514' lon='8.984906374095479' />
     631  <node id='-12' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.59361897336678' lon='8.985687593206816' />
     632  <node id='-10' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.59349189817163' lon='8.9824708670199'>
     633    <tag k='name' v='Invalid shape - should split into 3 individual shapes' />
     634  </node>
     635  <node id='-8' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.590687527911356' lon='8.98168069867828' />
     636  <node id='-6' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.59078239401975' lon='8.979861116140624' />
     637  <node id='-4' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.58659590060676' lon='8.979665773725651' />
     638  <node id='-2' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true' lat='49.586548447612444' lon='8.98191058921896' />
     639  <way id='-1445' action='modify' visible='true'>
     640    <nd ref='-1443' />
     641    <nd ref='-1444' />
     642    <nd ref='-1446' />
     643    <nd ref='-1448' />
     644    <nd ref='-1450' />
     645    <nd ref='-1452' />
     646    <nd ref='-1454' />
     647    <nd ref='-1456' />
     648    <nd ref='-1458' />
     649    <nd ref='-1460' />
     650    <nd ref='-1462' />
     651    <nd ref='-1464' />
     652    <nd ref='-1466' />
     653    <nd ref='-1468' />
     654    <nd ref='-1470' />
     655    <nd ref='-1472' />
     656    <nd ref='-1474' />
     657    <nd ref='-1476' />
     658    <nd ref='-1478' />
     659    <nd ref='-1480' />
     660    <nd ref='-1482' />
     661    <nd ref='-1484' />
     662    <nd ref='-1486' />
     663    <nd ref='-1488' />
     664    <nd ref='-1490' />
     665    <nd ref='-1492' />
     666    <nd ref='-1494' />
     667    <nd ref='-1496' />
     668    <nd ref='-1498' />
     669    <nd ref='-1500' />
     670    <nd ref='-1502' />
     671    <nd ref='-1504' />
     672    <nd ref='-1506' />
     673    <nd ref='-1508' />
     674    <nd ref='-1510' />
     675    <nd ref='-1512' />
     676    <nd ref='-1514' />
     677    <nd ref='-1516' />
     678    <nd ref='-1518' />
     679    <nd ref='-1520' />
     680    <nd ref='-1522' />
     681    <nd ref='-1524' />
     682    <nd ref='-1526' />
     683    <nd ref='-1528' />
     684    <nd ref='-1531' />
     685    <nd ref='-1533' />
     686    <nd ref='-1535' />
     687    <nd ref='-1537' />
     688    <nd ref='-1539' />
     689    <nd ref='-1541' />
     690    <nd ref='-1543' />
     691    <nd ref='-1545' />
     692    <nd ref='-1547' />
     693    <nd ref='-1549' />
     694    <nd ref='-1551' />
     695    <nd ref='-1553' />
     696    <nd ref='-1555' />
     697    <nd ref='-1557' />
     698    <nd ref='-1559' />
     699    <nd ref='-1561' />
     700    <nd ref='-1563' />
     701    <nd ref='-1565' />
     702    <nd ref='-1567' />
     703    <nd ref='-1569' />
     704    <nd ref='-1571' />
     705    <nd ref='-1573' />
     706    <nd ref='-1575' />
     707    <nd ref='-1577' />
     708    <nd ref='-1579' />
     709    <nd ref='-1581' />
     710    <nd ref='-1583' />
     711    <nd ref='-1585' />
     712    <nd ref='-1587' />
     713    <nd ref='-1589' />
     714    <nd ref='-1591' />
     715    <nd ref='-1443' />
     716    <tag k='building' v='yes' />
     717  </way>
     718  <way id='-1346' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     719    <nd ref='-1158' />
     720    <nd ref='-1160' />
     721    <nd ref='-1166' />
     722    <nd ref='-1168' />
     723    <nd ref='-1162' />
     724    <nd ref='-1158' />
     725    <tag k='building' v='yes' />
     726  </way>
     727  <way id='-1344' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     728    <nd ref='-1156' />
     729    <nd ref='-1158' />
     730    <nd ref='-1160' />
     731    <nd ref='-1162' />
     732    <nd ref='-1164' />
     733    <nd ref='-1156' />
     734    <tag k='building' v='yes' />
     735  </way>
     736  <way id='-1342' timestamp='2010-09-01T07:08:32Z' visible='true'>
     737    <nd ref='-1152' />
     738    <nd ref='-1154' />
     739    <tag k='highway' v='motorway' />
     740    <tag k='lanes' v='5' />
     741  </way>
     742  <way id='-1340' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     743    <nd ref='-1138' />
     744    <nd ref='-1146' />
     745    <nd ref='-1148' />
     746    <nd ref='-1150' />
     747    <nd ref='-1138' />
     748    <tag k='building' v='yes' />
     749  </way>
     750  <way id='-1338' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     751    <nd ref='-1138' />
     752    <nd ref='-1140' />
     753    <nd ref='-1142' />
     754    <nd ref='-1144' />
     755    <nd ref='-1138' />
     756    <tag k='building' v='yes' />
     757  </way>
     758  <way id='-1336' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     759    <nd ref='-1128' />
     760    <nd ref='-1132' />
     761    <nd ref='-1134' />
     762    <nd ref='-1136' />
     763    <nd ref='-1128' />
     764    <tag k='building' v='yes' />
     765  </way>
     766  <way id='-1334' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     767    <nd ref='-1124' />
     768    <nd ref='-1126' />
     769    <nd ref='-1136' />
     770    <nd ref='-1128' />
     771    <nd ref='-1132' />
     772    <nd ref='-1130' />
     773    <nd ref='-1124' />
     774    <tag k='building' v='yes' />
     775  </way>
     776  <way id='-1332' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     777    <nd ref='-1112' />
     778    <nd ref='-1118' />
     779    <nd ref='-1120' />
     780    <nd ref='-1122' />
     781    <nd ref='-1114' />
     782    <nd ref='-1112' />
     783    <tag k='building' v='yes' />
     784  </way>
     785  <way id='-1330' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     786    <nd ref='-1108' />
     787    <nd ref='-1110' />
     788    <nd ref='-1112' />
     789    <nd ref='-1114' />
     790    <nd ref='-1116' />
     791    <nd ref='-1108' />
     792    <tag k='building' v='yes' />
     793  </way>
     794  <way id='-1328' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true'>
     795    <nd ref='-1058' />
     796    <nd ref='-1102' />
     797    <nd ref='-1092' />
     798    <nd ref='-1084' />
     799    <nd ref='-1098' />
     800    <nd ref='-1088' />
     801    <nd ref='-1080' />
     802    <nd ref='-1074' />
     803    <nd ref='-1068' />
     804    <nd ref='-1062' />
     805    <nd ref='-1106' />
     806    <nd ref='-1096' />
     807    <nd ref='-1056' />
     808    <nd ref='-1100' />
     809    <nd ref='-1058' />
     810    <tag k='building' v='yes' />
     811    <tag k='source' v='cuzk:km' />
     812  </way>
     813  <way id='-1326' action='modify' timestamp='2010-09-01T07:22:22Z' visible='true'>
     814    <nd ref='-1090' />
     815    <nd ref='-1082' />
     816    <nd ref='-1076' />
     817    <nd ref='-1070' />
     818    <nd ref='-1064' />
     819    <nd ref='-1054' />
     820    <nd ref='-1066' />
     821    <nd ref='-1060' />
     822    <nd ref='-1104' />
     823    <nd ref='-1098' />
     824    <nd ref='-1094' />
     825    <nd ref='-1086' />
     826    <nd ref='-1078' />
     827    <nd ref='-1072' />
     828    <nd ref='-1090' />
     829    <tag k='building' v='yes' />
     830    <tag k='source' v='cuzk:km' />
     831  </way>
     832  <way id='-1324' timestamp='2010-09-01T07:19:58Z' visible='true'>
     833    <nd ref='-1050' />
     834    <nd ref='-1040' />
     835    <nd ref='-1052' />
     836    <nd ref='-1046' />
     837    <nd ref='-1050' />
     838    <tag k='building' v='yes' />
     839  </way>
     840  <way id='-1322' timestamp='2010-09-01T07:19:58Z' visible='true'>
     841    <nd ref='-1042' />
     842    <nd ref='-1038' />
     843    <nd ref='-1048' />
     844    <nd ref='-1044' />
     845    <nd ref='-1042' />
     846    <tag k='building' v='yes' />
     847  </way>
     848  <way id='-1320' action='modify' timestamp='2010-06-08T05:21:33Z' uid='213040' user='jf01' visible='true' version='7'>
     849    <nd ref='-904' />
     850    <nd ref='-948' />
     851    <nd ref='-988' />
     852    <nd ref='-1028' />
     853    <nd ref='-874' />
     854    <nd ref='-918' />
     855    <nd ref='-878' />
     856    <nd ref='-922' />
     857    <nd ref='-964' />
     858    <nd ref='-1004' />
     859    <nd ref='-852' />
     860    <nd ref='-892' />
     861    <nd ref='-936' />
     862    <nd ref='-976' />
     863    <nd ref='-940' />
     864    <nd ref='-978' />
     865    <nd ref='-1018' />
     866    <nd ref='-866' />
     867    <nd ref='-908' />
     868    <nd ref='-952' />
     869    <nd ref='-992' />
     870    <nd ref='-1032' />
     871    <nd ref='-996' />
     872    <nd ref='-1034' />
     873    <nd ref='-882' />
     874    <nd ref='-926' />
     875    <nd ref='-968' />
     876    <nd ref='-1006' />
     877    <nd ref='-854' />
     878    <nd ref='-894' />
     879    <nd ref='-858' />
     880    <nd ref='-898' />
     881    <nd ref='-944' />
     882    <nd ref='-982' />
     883    <nd ref='-978' />
     884    <nd ref='-940' />
     885    <nd ref='-976' />
     886    <nd ref='-1024' />
     887    <nd ref='-868' />
     888    <nd ref='-910' />
     889    <nd ref='-954' />
     890    <nd ref='-914' />
     891    <nd ref='-958' />
     892    <nd ref='-998' />
     893    <nd ref='-846' />
     894    <nd ref='-888' />
     895    <nd ref='-930' />
     896    <nd ref='-970' />
     897    <nd ref='-1010' />
     898    <nd ref='-928' />
     899    <nd ref='-966' />
     900    <nd ref='-1008' />
     901    <nd ref='-856' />
     902    <nd ref='-896' />
     903    <nd ref='-938' />
     904    <nd ref='-980' />
     905    <nd ref='-846' />
     906    <nd ref='-998' />
     907    <nd ref='-1020' />
     908    <nd ref='-984' />
     909    <nd ref='-1022' />
     910    <nd ref='-870' />
     911    <nd ref='-912' />
     912    <nd ref='-956' />
     913    <nd ref='-994' />
     914    <nd ref='-1036' />
     915    <nd ref='-884' />
     916    <nd ref='-848' />
     917    <nd ref='-886' />
     918    <nd ref='-932' />
     919    <nd ref='-972' />
     920    <nd ref='-1012' />
     921    <nd ref='-860' />
     922    <nd ref='-900' />
     923    <nd ref='-942' />
     924    <nd ref='-902' />
     925    <nd ref='-946' />
     926    <nd ref='-986' />
     927    <nd ref='-1026' />
     928    <nd ref='-872' />
     929    <nd ref='-916' />
     930    <nd ref='-960' />
     931    <nd ref='-1000' />
     932    <nd ref='-962' />
     933    <nd ref='-1002' />
     934    <nd ref='-850' />
     935    <nd ref='-890' />
     936    <nd ref='-934' />
     937    <nd ref='-974' />
     938    <nd ref='-1014' />
     939    <nd ref='-862' />
     940    <nd ref='-1016' />
     941    <nd ref='-864' />
     942    <nd ref='-906' />
     943    <nd ref='-950' />
     944    <nd ref='-990' />
     945    <nd ref='-1030' />
     946    <nd ref='-876' />
     947    <nd ref='-920' />
     948    <nd ref='-880' />
     949    <nd ref='-924' />
     950    <nd ref='-904' />
     951    <tag k='area' v='yes' />
     952    <tag k='highway' v='residential' />
     953    <tag k='source' v='cuzk:km' />
     954  </way>
     955  <way id='-1318' timestamp='2010-09-01T07:08:32Z' visible='true'>
     956    <nd ref='-842' />
     957    <nd ref='-844' />
     958    <tag k='highway' v='motorway' />
     959    <tag k='lanes' v='5' />
     960  </way>
     961  <way id='-1316' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     962    <nd ref='-834' />
     963    <nd ref='-828' />
     964    <nd ref='-836' />
     965    <nd ref='-822' />
     966    <nd ref='-820' />
     967    <nd ref='-838' />
     968    <nd ref='-816' />
     969    <nd ref='-840' />
     970    <nd ref='-834' />
     971    <tag k='building' v='yes' />
     972  </way>
     973  <way id='-1314' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     974    <nd ref='-810' />
     975    <nd ref='-826' />
     976    <nd ref='-828' />
     977    <nd ref='-834' />
     978    <nd ref='-832' />
     979    <nd ref='-816' />
     980    <nd ref='-830' />
     981    <nd ref='-812' />
     982    <nd ref='-810' />
     983    <tag k='building' v='yes' />
     984  </way>
     985  <way id='-1312' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     986    <nd ref='-808' />
     987    <nd ref='-810' />
     988    <nd ref='-812' />
     989    <nd ref='-814' />
     990    <nd ref='-816' />
     991    <nd ref='-818' />
     992    <nd ref='-820' />
     993    <nd ref='-822' />
     994    <nd ref='-824' />
     995    <nd ref='-808' />
     996    <tag k='building' v='yes' />
     997  </way>
     998  <way id='-1310' timestamp='2010-09-01T07:08:32Z' visible='true'>
     999    <nd ref='-804' />
     1000    <nd ref='-806' />
     1001    <tag k='highway' v='motorway' />
     1002    <tag k='lanes' v='5' />
     1003  </way>
     1004  <way id='-1308' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     1005    <nd ref='-782' />
     1006    <nd ref='-796' />
     1007    <nd ref='-798' />
     1008    <nd ref='-792' />
     1009    <nd ref='-790' />
     1010    <nd ref='-800' />
     1011    <nd ref='-786' />
     1012    <nd ref='-802' />
     1013    <nd ref='-782' />
     1014    <tag k='building' v='yes' />
     1015  </way>
     1016  <way id='-1306' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     1017    <nd ref='-780' />
     1018    <nd ref='-782' />
     1019    <nd ref='-784' />
     1020    <nd ref='-786' />
     1021    <nd ref='-788' />
     1022    <nd ref='-790' />
     1023    <nd ref='-792' />
     1024    <nd ref='-794' />
     1025    <nd ref='-780' />
     1026    <tag k='building' v='yes' />
     1027  </way>
     1028  <way id='-1304' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     1029    <nd ref='-772' />
     1030    <nd ref='-774' />
     1031    <nd ref='-776' />
     1032    <nd ref='-778' />
     1033    <nd ref='-772' />
     1034    <tag k='building' v='yes' />
     1035  </way>
     1036  <way id='-1302' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     1037    <nd ref='-766' />
     1038    <nd ref='-768' />
     1039    <nd ref='-770' />
     1040    <nd ref='-772' />
     1041    <nd ref='-766' />
     1042    <tag k='building' v='yes' />
     1043  </way>
     1044  <way id='-1300' action='modify' timestamp='2010-09-01T07:31:33Z' visible='true'>
     1045    <nd ref='-750' />
     1046    <nd ref='-752' />
     1047    <nd ref='-754' />
     1048    <nd ref='-756' />
     1049    <nd ref='-758' />
     1050    <nd ref='-760' />
     1051    <nd ref='-762' />
     1052    <nd ref='-764' />
     1053    <nd ref='-750' />
     1054    <tag k='building' v='yes' />
     1055  </way>
     1056  <way id='-1298' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1057    <nd ref='-738' />
     1058    <nd ref='-722' />
     1059    <nd ref='-740' />
     1060    <nd ref='-738' />
     1061    <tag k='building' v='yes' />
     1062    <tag k='name' v='A' />
     1063  </way>
     1064  <way id='-1296' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1065    <nd ref='-746' />
     1066    <nd ref='-730' />
     1067    <nd ref='-734' />
     1068    <nd ref='-724' />
     1069    <nd ref='-738' />
     1070    <nd ref='-746' />
     1071    <tag k='building' v='yes' />
     1072    <tag k='name' v='A' />
     1073  </way>
     1074  <way id='-1294' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1075    <nd ref='-732' />
     1076    <nd ref='-742' />
     1077    <nd ref='-726' />
     1078    <nd ref='-732' />
     1079    <tag k='building' v='yes' />
     1080    <tag k='name' v='B' />
     1081  </way>
     1082  <way id='-1292' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1083    <nd ref='-720' />
     1084    <nd ref='-744' />
     1085    <nd ref='-728' />
     1086    <nd ref='-736' />
     1087    <nd ref='-732' />
     1088    <nd ref='-720' />
     1089    <tag k='building' v='yes' />
     1090    <tag k='name' v='B' />
     1091  </way>
     1092  <way id='-1290' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1093    <nd ref='-716' />
     1094    <nd ref='-708' />
     1095    <nd ref='-222' />
     1096    <nd ref='-716' />
     1097    <tag k='building' v='yes' />
     1098    <tag k='name' v='A' />
     1099  </way>
     1100  <way id='-1288' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1101    <nd ref='-718' />
     1102    <nd ref='-712' />
     1103    <nd ref='-714' />
     1104    <nd ref='-710' />
     1105    <nd ref='-716' />
     1106    <nd ref='-718' />
     1107    <tag k='building' v='yes' />
     1108    <tag k='name' v='A' />
     1109  </way>
     1110  <way id='-1286' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1111    <nd ref='-704' />
     1112    <nd ref='-706' />
     1113    <tag k='highway' v='motorway' />
     1114    <tag k='lanes' v='5' />
     1115  </way>
     1116  <way id='-1284' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1117    <nd ref='-700' />
     1118    <nd ref='-702' />
     1119    <tag k='highway' v='motorway' />
     1120    <tag k='lanes' v='5' />
     1121  </way>
     1122  <way id='-1282' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1123    <nd ref='-674' />
     1124    <nd ref='-686' />
     1125    <nd ref='-696' />
     1126    <nd ref='-676' />
     1127    <nd ref='-670' />
     1128    <nd ref='-680' />
     1129    <nd ref='-684' />
     1130    <nd ref='-688' />
     1131    <nd ref='-674' />
     1132    <tag k='building' v='yes' />
     1133  </way>
     1134  <way id='-1280' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1135    <nd ref='-688' />
     1136    <nd ref='-698' />
     1137    <nd ref='-682' />
     1138    <nd ref='-694' />
     1139    <nd ref='-696' />
     1140    <nd ref='-676' />
     1141    <nd ref='-678' />
     1142    <nd ref='-690' />
     1143    <nd ref='-670' />
     1144    <nd ref='-680' />
     1145    <nd ref='-692' />
     1146    <nd ref='-672' />
     1147    <nd ref='-684' />
     1148    <nd ref='-688' />
     1149    <tag k='building' v='yes' />
     1150  </way>
     1151  <way id='-1278' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1152    <nd ref='-224' />
     1153    <nd ref='-226' />
     1154    <nd ref='-228' />
     1155    <nd ref='-230' />
     1156    <nd ref='-224' />
     1157    <tag k='amenity' v='parking' />
     1158    <tag k='parking' v='surface' />
     1159  </way>
     1160  <way id='-1276' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1161    <nd ref='-360' />
     1162    <nd ref='-352' />
     1163    <nd ref='-354' />
     1164    <nd ref='-356' />
     1165    <nd ref='-358' />
     1166    <nd ref='-360' />
     1167    <tag k='amenity' v='parking' />
     1168    <tag k='parking' v='surface' />
     1169  </way>
     1170  <way id='-1274' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1171    <nd ref='-506' />
     1172    <nd ref='-468' />
     1173    <nd ref='-498' />
     1174    <nd ref='-466' />
     1175    <nd ref='-506' />
     1176    <tag k='amenity' v='parking' />
     1177    <tag k='parking' v='surface' />
     1178  </way>
     1179  <way id='-1272' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1180    <nd ref='-382' />
     1181    <nd ref='-394' />
     1182    <tag k='highway' v='motorway' />
     1183    <tag k='lanes' v='5' />
     1184  </way>
     1185  <way id='-1270' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1186    <nd ref='-392' />
     1187    <nd ref='-398' />
     1188    <tag k='highway' v='motorway' />
     1189    <tag k='lanes' v='5' />
     1190  </way>
     1191  <way id='-1268' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1192    <nd ref='-364' />
     1193    <nd ref='-366' />
     1194    <nd ref='-376' />
     1195    <nd ref='-372' />
     1196    <nd ref='-370' />
     1197    <nd ref='-364' />
     1198    <tag k='amenity' v='parking' />
     1199    <tag k='parking' v='surface' />
     1200  </way>
     1201  <way id='-1266' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1202    <nd ref='-274' />
     1203    <nd ref='-254' />
     1204    <nd ref='-260' />
     1205    <nd ref='-270' />
     1206    <nd ref='-268' />
     1207    <nd ref='-274' />
     1208    <tag k='landuse' v='retail' />
     1209  </way>
     1210  <way id='-1264' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1211    <nd ref='-574' />
     1212    <nd ref='-572' />
     1213    <tag k='highway' v='motorway' />
     1214    <tag k='lanes' v='5' />
     1215  </way>
     1216  <way id='-1262' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1217    <nd ref='-258' />
     1218    <nd ref='-322' />
     1219    <nd ref='-320' />
     1220    <nd ref='-328' />
     1221    <nd ref='-330' />
     1222    <nd ref='-334' />
     1223    <nd ref='-332' />
     1224    <nd ref='-324' />
     1225    <nd ref='-250' />
     1226    <nd ref='-252' />
     1227    <nd ref='-258' />
     1228    <tag k='amenity' v='parking' />
     1229    <tag k='parking' v='surface' />
     1230  </way>
     1231  <way id='-1260' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1232    <nd ref='-504' />
     1233    <nd ref='-508' />
     1234    <nd ref='-502' />
     1235    <nd ref='-464' />
     1236    <nd ref='-504' />
     1237  </way>
     1238  <way id='-1258' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1239    <nd ref='-540' />
     1240    <nd ref='-492' />
     1241    <nd ref='-490' />
     1242    <nd ref='-536' />
     1243    <nd ref='-540' />
     1244  </way>
     1245  <way id='-1256' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1246    <nd ref='-560' />
     1247    <nd ref='-562' />
     1248    <nd ref='-568' />
     1249    <nd ref='-570' />
     1250    <nd ref='-560' />
     1251    <tag k='amenity' v='parking' />
     1252    <tag k='parking' v='surface' />
     1253  </way>
     1254  <way id='-1254' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1255    <nd ref='-634' />
     1256    <nd ref='-636' />
     1257    <nd ref='-638' />
     1258    <nd ref='-662' />
     1259    <nd ref='-634' />
     1260    <tag k='amenity' v='parking' />
     1261    <tag k='parking' v='surface' />
     1262  </way>
     1263  <way id='-1252' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1264    <nd ref='-544' />
     1265    <nd ref='-546' />
     1266    <nd ref='-556' />
     1267    <nd ref='-558' />
     1268    <nd ref='-544' />
     1269    <tag k='amenity' v='parking' />
     1270    <tag k='parking' v='surface' />
     1271  </way>
     1272  <way id='-1250' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1273    <nd ref='-642' />
     1274    <nd ref='-656' />
     1275    <nd ref='-658' />
     1276    <nd ref='-652' />
     1277    <nd ref='-650' />
     1278    <nd ref='-648' />
     1279    <nd ref='-646' />
     1280    <nd ref='-640' />
     1281    <nd ref='-644' />
     1282    <nd ref='-660' />
     1283    <nd ref='-668' />
     1284    <nd ref='-654' />
     1285    <nd ref='-642' />
     1286    <tag k='building' v='yes' />
     1287  </way>
     1288  <way id='-1248' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1289    <nd ref='-286' />
     1290    <nd ref='-256' />
     1291    <nd ref='-282' />
     1292    <tag k='highway' v='footway' />
     1293  </way>
     1294  <way id='-1246' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1295    <nd ref='-496' />
     1296    <nd ref='-510' />
     1297    <nd ref='-470' />
     1298    <nd ref='-500' />
     1299    <nd ref='-496' />
     1300  </way>
     1301  <way id='-1244' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1302    <nd ref='-452' />
     1303    <nd ref='-448' />
     1304    <nd ref='-476' />
     1305    <nd ref='-460' />
     1306    <nd ref='-452' />
     1307  </way>
     1308  <way id='-1242' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1309    <nd ref='-482' />
     1310    <nd ref='-480' />
     1311    <nd ref='-486' />
     1312    <nd ref='-484' />
     1313    <nd ref='-482' />
     1314  </way>
     1315  <way id='-1240' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1316    <nd ref='-528' />
     1317    <nd ref='-530' />
     1318    <nd ref='-488' />
     1319    <nd ref='-534' />
     1320    <nd ref='-528' />
     1321  </way>
     1322  <way id='-1238' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1323    <nd ref='-396' />
     1324    <nd ref='-386' />
     1325    <tag k='highway' v='motorway' />
     1326    <tag k='lanes' v='5' />
     1327  </way>
     1328  <way id='-1236' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1329    <nd ref='-578' />
     1330    <nd ref='-588' />
     1331    <nd ref='-590' />
     1332    <nd ref='-584' />
     1333    <nd ref='-586' />
     1334    <nd ref='-608' />
     1335    <nd ref='-628' />
     1336    <nd ref='-626' />
     1337    <nd ref='-632' />
     1338    <nd ref='-630' />
     1339    <nd ref='-620' />
     1340    <nd ref='-578' />
     1341    <tag k='amenity' v='parking' />
     1342    <tag k='parking' v='surface' />
     1343  </way>
     1344  <way id='-1234' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1345    <nd ref='-654' />
     1346    <nd ref='-642' />
     1347    <nd ref='-648' />
     1348    <nd ref='-646' />
     1349    <nd ref='-654' />
     1350    <tag k='building' v='yes' />
     1351  </way>
     1352  <way id='-1232' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1353    <nd ref='-232' />
     1354    <nd ref='-234' />
     1355    <nd ref='-236' />
     1356    <nd ref='-238' />
     1357    <nd ref='-240' />
     1358    <nd ref='-232' />
     1359    <tag k='amenity' v='parking' />
     1360    <tag k='parking' v='surface' />
     1361  </way>
     1362  <way id='-1230' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1363    <nd ref='-592' />
     1364    <nd ref='-600' />
     1365    <nd ref='-594' />
     1366    <nd ref='-604' />
     1367    <nd ref='-582' />
     1368    <nd ref='-576' />
     1369    <nd ref='-602' />
     1370    <nd ref='-580' />
     1371    <nd ref='-596' />
     1372    <nd ref='-592' />
     1373    <tag k='amenity' v='parking' />
     1374  </way>
     1375  <way id='-1228' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1376    <nd ref='-266' />
     1377    <nd ref='-264' />
     1378    <nd ref='-256' />
     1379    <nd ref='-262' />
     1380    <nd ref='-266' />
     1381    <tag k='landuse' v='basin' />
     1382  </way>
     1383  <way id='-1226' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1384    <nd ref='-638' />
     1385    <nd ref='-664' />
     1386    <nd ref='-666' />
     1387    <nd ref='-662' />
     1388    <nd ref='-638' />
     1389    <tag k='amenity' v='parking' />
     1390    <tag k='parking' v='surface' />
     1391  </way>
     1392  <way id='-1224' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1393    <nd ref='-404' />
     1394    <nd ref='-428' />
     1395    <nd ref='-430' />
     1396  </way>
     1397  <way id='-1222' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1398    <nd ref='-342' />
     1399    <nd ref='-340' />
     1400    <nd ref='-338' />
     1401    <nd ref='-336' />
     1402    <nd ref='-342' />
     1403    <tag k='amenity' v='parking' />
     1404    <tag k='parking' v='surface' />
     1405  </way>
     1406  <way id='-1220' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1407    <nd ref='-606' />
     1408    <nd ref='-600' />
     1409    <nd ref='-594' />
     1410    <nd ref='-604' />
     1411    <nd ref='-582' />
     1412    <nd ref='-576' />
     1413    <nd ref='-602' />
     1414    <nd ref='-580' />
     1415    <nd ref='-598' />
     1416    <nd ref='-606' />
     1417    <tag k='amenity' v='parking' />
     1418  </way>
     1419  <way id='-1218' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1420    <nd ref='-472' />
     1421    <nd ref='-474' />
     1422    <tag k='highway' v='motorway' />
     1423    <tag k='lanes' v='5' />
     1424  </way>
     1425  <way id='-1216' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1426    <nd ref='-272' />
     1427    <nd ref='-252' />
     1428    <nd ref='-276' />
     1429    <tag k='highway' v='footway' />
     1430  </way>
     1431  <way id='-1214' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1432    <nd ref='-378' />
     1433    <nd ref='-380' />
     1434    <tag k='highway' v='motorway' />
     1435    <tag k='lanes' v='5' />
     1436  </way>
     1437  <way id='-1212' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1438    <nd ref='-462' />
     1439    <nd ref='-458' />
     1440    <nd ref='-478' />
     1441    <nd ref='-450' />
     1442    <nd ref='-462' />
     1443    <tag k='amenity' v='parking' />
     1444    <tag k='parking' v='surface' />
     1445  </way>
     1446  <way id='-1210' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1447    <nd ref='-446' />
     1448    <nd ref='-416' />
     1449    <nd ref='-422' />
     1450    <nd ref='-418' />
     1451    <nd ref='-446' />
     1452  </way>
     1453  <way id='-1208' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1454    <nd ref='-310' />
     1455    <nd ref='-314' />
     1456    <nd ref='-304' />
     1457    <nd ref='-326' />
     1458    <nd ref='-298' />
     1459    <nd ref='-306' />
     1460    <nd ref='-318' />
     1461    <nd ref='-316' />
     1462    <nd ref='-312' />
     1463    <nd ref='-308' />
     1464    <nd ref='-310' />
     1465    <tag k='amenity' v='parking' />
     1466    <tag k='parking' v='surface' />
     1467  </way>
     1468  <way id='-1206' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1469    <nd ref='-384' />
     1470    <nd ref='-390' />
     1471    <nd ref='-388' />
     1472    <nd ref='-410' />
     1473    <nd ref='-408' />
     1474    <nd ref='-414' />
     1475    <nd ref='-412' />
     1476    <nd ref='-402' />
     1477    <nd ref='-400' />
     1478    <nd ref='-406' />
     1479    <nd ref='-384' />
     1480    <tag k='amenity' v='parking' />
     1481    <tag k='parking' v='surface' />
     1482  </way>
     1483  <way id='-1204' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1484    <nd ref='-344' />
     1485    <nd ref='-346' />
     1486    <nd ref='-352' />
     1487    <nd ref='-358' />
     1488    <nd ref='-348' />
     1489    <nd ref='-350' />
     1490    <nd ref='-344' />
     1491    <tag k='amenity' v='parking' />
     1492    <tag k='parking' v='surface' />
     1493  </way>
     1494  <way id='-1202' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1495    <nd ref='-618' />
     1496    <nd ref='-624' />
     1497    <nd ref='-620' />
     1498    <nd ref='-630' />
     1499    <nd ref='-632' />
     1500    <nd ref='-622' />
     1501    <nd ref='-612' />
     1502    <nd ref='-584' />
     1503    <nd ref='-590' />
     1504    <nd ref='-610' />
     1505    <nd ref='-616' />
     1506    <nd ref='-614' />
     1507    <nd ref='-618' />
     1508    <tag k='amenity' v='parking' />
     1509    <tag k='parking' v='surface' />
     1510  </way>
     1511  <way id='-1200' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1512    <nd ref='-420' />
     1513    <nd ref='-426' />
     1514    <nd ref='-424' />
     1515    <nd ref='-444' />
     1516    <nd ref='-420' />
     1517    <tag k='amenity' v='parking' />
     1518    <tag k='parking' v='surface' />
     1519  </way>
     1520  <way id='-1198' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1521    <nd ref='-242' />
     1522    <nd ref='-244' />
     1523    <nd ref='-246' />
     1524    <nd ref='-248' />
     1525    <nd ref='-242' />
     1526    <tag k='amenity' v='parking' />
     1527    <tag k='parking' v='surface' />
     1528  </way>
     1529  <way id='-1196' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1530    <nd ref='-362' />
     1531    <nd ref='-376' />
     1532    <nd ref='-368' />
     1533    <nd ref='-374' />
     1534    <nd ref='-362' />
     1535    <tag k='amenity' v='parking' />
     1536    <tag k='parking' v='surface' />
     1537  </way>
     1538  <way id='-1194' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1539    <nd ref='-440' />
     1540    <nd ref='-442' />
     1541    <nd ref='-436' />
     1542    <nd ref='-438' />
     1543    <nd ref='-440' />
     1544  </way>
     1545  <way id='-1192' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1546    <nd ref='-538' />
     1547    <nd ref='-532' />
     1548    <nd ref='-542' />
     1549    <nd ref='-494' />
     1550    <nd ref='-538' />
     1551    <tag k='amenity' v='parking' />
     1552    <tag k='parking' v='surface' />
     1553  </way>
     1554  <way id='-1190' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1555    <nd ref='-278' />
     1556    <nd ref='-300' />
     1557    <nd ref='-290' />
     1558    <nd ref='-296' />
     1559    <nd ref='-302' />
     1560    <nd ref='-292' />
     1561    <nd ref='-284' />
     1562    <nd ref='-288' />
     1563    <nd ref='-294' />
     1564    <nd ref='-280' />
     1565    <nd ref='-278' />
     1566    <tag k='amenity' v='parking' />
     1567    <tag k='parking' v='surface' />
     1568  </way>
     1569  <way id='-1188' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1570    <nd ref='-456' />
     1571    <nd ref='-434' />
     1572    <nd ref='-432' />
     1573    <nd ref='-454' />
     1574    <nd ref='-456' />
     1575  </way>
     1576  <way id='-1186' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1577    <nd ref='-550' />
     1578    <nd ref='-548' />
     1579    <nd ref='-554' />
     1580    <nd ref='-552' />
     1581    <nd ref='-550' />
     1582    <tag k='amenity' v='parking' />
     1583    <tag k='name' v='Outer blob' />
     1584    <tag k='parking' v='surface' />
     1585  </way>
     1586  <way id='-1184' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1587    <nd ref='-564' />
     1588    <nd ref='-524' />
     1589    <nd ref='-516' />
     1590    <nd ref='-514' />
     1591    <nd ref='-518' />
     1592    <nd ref='-512' />
     1593    <nd ref='-526' />
     1594    <nd ref='-566' />
     1595    <nd ref='-522' />
     1596    <nd ref='-520' />
     1597    <nd ref='-564' />
     1598    <tag k='name' v='Thing in the Middle' />
     1599  </way>
     1600  <way id='-1182' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true'>
     1601    <nd ref='-220' />
     1602    <nd ref='-218' />
     1603    <nd ref='-216' />
     1604    <nd ref='-214' />
     1605    <nd ref='-212' />
     1606    <nd ref='-210' />
     1607    <nd ref='-208' />
     1608    <nd ref='-206' />
     1609    <nd ref='-220' />
     1610    <tag k='building' v='yes' />
     1611  </way>
     1612  <way id='-1180' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true'>
     1613    <nd ref='-192' />
     1614    <nd ref='-204' />
     1615    <nd ref='-202' />
     1616    <nd ref='-200' />
     1617    <nd ref='-198' />
     1618    <nd ref='-196' />
     1619    <nd ref='-194' />
     1620    <nd ref='-192' />
     1621    <tag k='building' v='yes' />
     1622  </way>
     1623  <way id='-1178' action='modify' timestamp='2010-09-01T07:34:34Z' visible='true'>
     1624    <nd ref='-140' />
     1625    <nd ref='-132' />
     1626    <nd ref='-146' />
     1627    <nd ref='-104' />
     1628    <nd ref='-140' />
     1629  </way>
     1630  <way id='-1174' action='modify' timestamp='2010-09-01T07:34:34Z' visible='true'>
     1631    <nd ref='-180' />
     1632    <nd ref='-116' />
     1633    <nd ref='-78' />
     1634    <nd ref='-140' />
     1635    <nd ref='-180' />
     1636  </way>
     1637  <way id='-1172' action='modify' timestamp='2010-08-22T06:58:34Z' visible='true'>
     1638    <nd ref='-180' />
     1639    <nd ref='-170' />
     1640    <nd ref='-100' />
     1641    <nd ref='-128' />
     1642    <nd ref='-156' />
     1643    <nd ref='-180' />
     1644    <tag k='natural' v='water' />
     1645  </way>
     1646  <way id='-1170' action='modify' timestamp='2010-09-01T07:44:52Z' visible='true'>
     1647    <nd ref='-8' />
     1648    <nd ref='-18' />
     1649    <nd ref='-16' />
     1650    <nd ref='-14' />
     1651    <nd ref='-12' />
     1652    <nd ref='-10' />
     1653    <nd ref='-8' />
     1654    <nd ref='-6' />
     1655    <nd ref='-4' />
     1656    <nd ref='-2' />
     1657    <nd ref='-8' />
     1658    <tag k='building' v='yes' />
     1659  </way>
     1660  <relation id='-1364' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1661    <member type='way' ref='-1206' role='area' />
     1662    <member type='node' ref='-408' role='node in area' />
     1663    <member type='node' ref='-412' role='node in area' />
     1664    <member type='way' ref='-1224' role='some other way' />
     1665    <member type='node' ref='-402' role='to be deleted node in area' />
     1666    <tag k='name' v='1.' />
     1667  </relation>
     1668  <relation id='-1362' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1669    <member type='way' ref='-1244' role='inner' />
     1670    <member type='way' ref='-1212' role='outer' />
     1671    <tag k='name' v='3.' />
     1672    <tag k='type' v='multipolygon' />
     1673  </relation>
     1674  <relation id='-1360' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1675    <member type='way' ref='-1242' role='' />
     1676    <member type='way' ref='-1246' role='' />
     1677    <tag k='name ' v='4. b' />
     1678  </relation>
     1679  <relation id='-1358' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1680  </relation>
     1681  <relation id='-1356' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1682    <member type='way' ref='-1210' role='inner' />
     1683    <member type='way' ref='-1200' role='outer' />
     1684    <tag k='name' v='2.' />
     1685    <tag k='type' v='multipolygon' />
     1686  </relation>
     1687  <relation id='-1354' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1688    <member type='way' ref='-1260' role='inner' />
     1689    <member type='way' ref='-1274' role='outer' />
     1690    <tag k='name' v='4. a' />
     1691    <tag k='type' v='multipolygon' />
     1692  </relation>
     1693  <relation id='-1352' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1694    <member type='way' ref='-1240' role='inner' />
     1695    <member type='way' ref='-1258' role='inner' />
     1696    <member type='way' ref='-1192' role='outer' />
     1697    <tag k='name' v='5.' />
     1698    <tag k='type' v='multipolygon' />
     1699  </relation>
     1700  <relation id='-1350' timestamp='2010-09-01T07:08:32Z' visible='true'>
     1701    <member type='way' ref='-1184' role='inner' />
     1702    <member type='way' ref='-1186' role='outer' />
     1703    <tag k='name' v='6.' />
     1704    <tag k='type' v='multipolygon' />
     1705  </relation>
     1706  <relation id='-1348' timestamp='2010-09-01T07:44:52Z' visible='true'>
     1707    <member type='way' ref='-1172' role='outer' />
     1708    <member type='way' ref='-1174' role='inner' />
     1709    <member type='way' ref='-1178' role='inner' />
     1710    <tag k='natural' v='water' />
     1711    <tag k='type' v='multipolygon' />
     1712  </relation>
     1713</osm>
  • src/org/openstreetmap/josm/actions/CombineWayAction.java

     
    9999     *
    100100     * @return the set of referring relations
    101101     */
    102     protected Set<Relation> getParentRelations(Collection<Way> ways) {
     102    public static Set<Relation> getParentRelations(Collection<Way> ways) {
    103103        HashSet<Relation> ret = new HashSet<Relation>();
    104104        for (Way w: ways) {
    105105            ret.addAll(OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class));
  • src/org/openstreetmap/josm/actions/JoinAreasAction.java

     
    11// License: GPL. Copyright 2007 by Immanuel Scholz and others
    22package org.openstreetmap.josm.actions;
    33
     4import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.combineTigerTags;
     5import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.completeTagCollectionForEditing;
     6import static org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing;
    47import static org.openstreetmap.josm.tools.I18n.marktr;
    58import static org.openstreetmap.josm.tools.I18n.tr;
    69import static org.openstreetmap.josm.tools.I18n.trn;
    710
    8 import java.awt.GridBagLayout;
    911import java.awt.event.ActionEvent;
    1012import java.awt.event.KeyEvent;
    1113import java.awt.geom.Area;
     
    1315import java.util.ArrayList;
    1416import java.util.Collection;
    1517import java.util.Collections;
     18import java.util.Comparator;
    1619import java.util.HashMap;
    1720import java.util.HashSet;
     21import java.util.LinkedHashSet;
    1822import java.util.LinkedList;
    1923import java.util.List;
    2024import java.util.Map;
    21 import java.util.Map.Entry;
    2225import java.util.Set;
    2326import java.util.TreeMap;
    24 import java.util.TreeSet;
    2527
    26 import javax.swing.Box;
    27 import javax.swing.JComboBox;
    28 import javax.swing.JLabel;
    2928import javax.swing.JOptionPane;
    30 import javax.swing.JPanel;
    3129
    3230import org.openstreetmap.josm.Main;
    3331import org.openstreetmap.josm.actions.SplitWayAction.SplitWayResult;
     
    4442import org.openstreetmap.josm.data.osm.OsmPrimitive;
    4543import org.openstreetmap.josm.data.osm.Relation;
    4644import org.openstreetmap.josm.data.osm.RelationMember;
    47 import org.openstreetmap.josm.data.osm.TigerUtils;
     45import org.openstreetmap.josm.data.osm.TagCollection;
    4846import org.openstreetmap.josm.data.osm.Way;
    49 import org.openstreetmap.josm.gui.ExtendedDialog;
    50 import org.openstreetmap.josm.tools.GBC;
     47import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog;
    5148import org.openstreetmap.josm.tools.Shortcut;
    5249
    5350public class JoinAreasAction extends JosmAction {
     
    5552    private LinkedList<Command> cmds = new LinkedList<Command>();
    5653    private int cmdsCount = 0;
    5754
     55
    5856    /**
    5957     * This helper class describes join ares action result.
    6058     * @author viesturs
    6159     *
    6260     */
    63     public static class JoinAreasResult {
     61    public static class JoinAreasResult{
    6462
    65         public Way outerWay;
    66         public List<Way> innerWays;
    67 
    6863        public boolean mergeSuccessful;
    6964        public boolean hasChanges;
    7065        public boolean hasRelationProblems;
     66
     67        public List<ComplexPolygon> polygons;
    7168    }
    7269
    73     // HelperClass
    74     // Saves a node and two positions where to insert the node into the ways
    75     private static class NodeToSegs implements Comparable<NodeToSegs> {
    76         public int pos;
    77         public Node n;
    78         public double dis;
    79         public NodeToSegs(int pos, Node n, LatLon dis) {
    80             this.pos = pos;
    81             this.n = n;
    82             this.dis = n.getCoor().greatCircleDistance(dis);
    83         }
     70    public static class ComplexPolygon{
     71        public Way outerWay;
     72        public List<Way> innerWays;
    8473
    85         public int compareTo(NodeToSegs o) {
    86             if(this.pos == o.pos)
    87                 return (this.dis - o.dis) > 0 ? 1 : -1;
    88                 return this.pos - o.pos;
     74        public ComplexPolygon(Way way){
     75            outerWay = way;
     76            innerWays = new ArrayList<Way>();
    8977        }
    90 
    91         @Override
    92         public int hashCode() {
    93             return pos;
    94         }
    95 
    96         @Override
    97         public boolean equals(Object o) {
    98             if (o instanceof NodeToSegs)
    99                 return compareTo((NodeToSegs) o) == 0;
    100             else
    101                 return false;
    102         }
    10378    }
    10479
    10580    // HelperClass
     
    125100        }
    126101    }
    127102
    128     /**
    129      * HelperClass
    130      * saves a way and the "inside" side
    131      * insideToTheLeft: if true left side is "in", false -right side is "in".
    132      * Left and right are determined along the orientation of way.
    133      */
    134     private static class WayInPath {
     103
     104    //HelperClass
     105    //saves a way and the "inside" side
     106    // insideToTheLeft: if true left side is "in", false -right side is "in". Left and right are determined along the orientation of way.
     107    private static class WayInPath{
    135108        public final Way way;
    136         public boolean insideToTheLeft;
     109        public boolean insideToTheRight;
    137110
    138         public WayInPath(Way way, boolean insideLeft) {
    139             this.way = way;
    140             this.insideToTheLeft = insideLeft;
     111        public WayInPath(Way _way, boolean _insideRight){
     112            this.way = _way;
     113            this.insideToTheRight = _insideRight;
    141114        }
    142115
    143116        @Override
     
    147120
    148121        @Override
    149122        public boolean equals(Object other) {
    150             if (!(other instanceof WayInPath))
    151                 return false;
     123            if (!(other instanceof WayInPath)) return false;
    152124            WayInPath otherMember = (WayInPath) other;
    153             return otherMember.way.equals(this.way) && otherMember.insideToTheLeft == this.insideToTheLeft;
     125            return otherMember.way.equals(this.way) && otherMember.insideToTheRight == this.insideToTheRight;
    154126        }
    155127    }
    156128
     129    /**
     130     * This hepler class implements algorithm traversing trough connected ways.
     131     * Assumes you are going in clockwise orientation.
     132     * @author viesturs
     133     *
     134     */
     135    private static class WayTraverser {
     136
     137        private Set<WayInPath> availableWays;
     138        private WayInPath lastWay;
     139        private boolean lastWayReverse;
     140
     141        public WayTraverser(Collection<WayInPath> ways){
     142
     143            availableWays = new HashSet<WayInPath>(ways);
     144            lastWay = null;
     145        }
     146
     147        public void removeWays(Collection<WayInPath> ways){
     148            availableWays.removeAll(ways);
     149        }
     150
     151        public boolean hasWays(){
     152            return availableWays.size() > 0;
     153        }
     154
     155        public WayInPath startNewWay(WayInPath way) {
     156            lastWay = way;
     157            lastWayReverse = !lastWay.insideToTheRight;
     158
     159            return lastWay;
     160        }
     161
     162        public WayInPath startNewWay() {
     163            if (availableWays.size() == 0) {
     164                lastWay = null;
     165            } else {
     166                lastWay = availableWays.iterator().next();
     167                lastWayReverse = !lastWay.insideToTheRight;
     168            }
     169
     170            return lastWay;
     171        }
     172
     173
     174        public  WayInPath advanceNextLeftmostWay(){
     175            return advanceNextWay(false);
     176        }
     177
     178        public  WayInPath advanceNextRightmostWay(){
     179            return advanceNextWay(true);
     180        }
     181
     182        private WayInPath advanceNextWay(boolean rightmost){
     183
     184            Node headNode = !lastWayReverse ? lastWay.way.lastNode() : lastWay.way.firstNode();
     185            Node prevNode = !lastWayReverse ? lastWay.way.getNode(lastWay.way.getNodesCount() - 2) : lastWay.way.getNode(1);
     186
     187            //find best next way
     188            WayInPath bestWay = null;
     189            Node bestWayNextNode = null;
     190            boolean bestWayReverse = false;
     191
     192            for(WayInPath way: availableWays)
     193            {
     194                if (way.way.firstNode().equals(headNode)){
     195                    //start adjacent to headNode
     196                    Node nextNode = way.way.getNode(1);
     197
     198                    if (nextNode.equals(prevNode))
     199                    {
     200                        //this is the path we came from - ignore it.
     201                    }
     202                    else if (bestWay == null || (isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode) == rightmost) )
     203                    {
     204                        //the new way is better
     205                        bestWay = way;
     206                        bestWayReverse = false;
     207                        bestWayNextNode = nextNode;
     208                    }
     209                }
     210
     211                if (way.way.lastNode().equals(headNode))
     212                {
     213                    //end adjacent to headNode
     214                    Node nextNode = way.way.getNode(way.way.getNodesCount() - 2);
     215
     216                    if (nextNode.equals(prevNode))
     217                    {
     218                        //this is the path we came from - ignore it.
     219                    }
     220                    else if (bestWay == null || (isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode) == rightmost))
     221                    {
     222                        //the new way is better
     223                        bestWay = way;
     224                        bestWayReverse = true;
     225                        bestWayNextNode = nextNode;
     226                    }
     227                }
     228            }
     229
     230            lastWay = bestWay;
     231            lastWayReverse = bestWayReverse;
     232
     233            return lastWay;
     234        }
     235
     236        public boolean isLastWayInsideToTheRight(){
     237            return lastWayReverse != lastWay.insideToTheRight;
     238        }
     239    }
     240
     241    /**
     242     * Provides some node order , based on coordinates, nodes with equal coordinates are equal.
     243     * @author viesturs
     244     *
     245     */
     246    private class NodePositionComparator implements Comparator<Node>{
     247
     248        @Override
     249        public int compare(Node n1, Node n2) {
     250
     251            double dLat = n1.getCoor().lat() - n2.getCoor().lat();
     252            double dLon = n1.getCoor().lon() - n2.getCoor().lon();
     253
     254            if (dLat > 0)
     255                return 1;
     256            else if (dLat < 0)
     257                return -1;
     258            else if (dLon == 0) //dlat is 0 here
     259                return 0;
     260            else
     261                return dLon > 0 ? 1: -1;
     262        }
     263    }
     264
     265
     266    /**
     267     * Helper storage class for finding findOuterWays
     268     * @author viesturs
     269     */
     270    static class PolygonLevel{
     271        public final int level;
     272        public final ComplexPolygon pol;
     273
     274        public PolygonLevel(ComplexPolygon _pol, int _level){
     275            pol = _pol;
     276            level = _level;
     277        }
     278    }
     279
     280
    157281    // Adds the menu entry, Shortcuts, etc.
    158282    public JoinAreasAction() {
    159283        super(tr("Join overlapping Areas"), "joinareas", tr("Joins areas that overlap each other"), Shortcut.registerShortcut("tools:joinareas", tr("Tool: {0}", tr("Join overlapping Areas")),
     
    172296            return;
    173297        }
    174298
    175         // Too many ways
    176         if(ways.size() > 2) {
    177             JOptionPane.showMessageDialog(Main.parent, tr("Only up to two areas can be joined at the moment."));
    178             return;
    179         }
    180 
    181299        List<Node> allNodes = new ArrayList<Node>();
    182300        for (Way way: ways) {
    183301            if(!way.isClosed()) {
     
    208326            }
    209327        }
    210328
    211         if (checkForTagConflicts(ways.getFirst(), ways.getLast()))
    212             //there was conflicts and user canceled abort the action.
     329        //analyze multipolygon relations and collect all areas
     330        List<ComplexPolygon> areas = collectAreas(ways);
     331
     332        if (areas == null)
     333            //too complex multipolygon relations found
    213334            return;
    214335
     336        if (!testJoin(areas))
     337        {
     338            JOptionPane.showMessageDialog(Main.parent, tr("No intersection found. Nothing was changed."));
     339            return;
     340        }
    215341
    216         JoinAreasResult result = joinAreas(ways.getFirst(), ways.getLast());
     342        if(!resolveTagConflicts(ways))
     343            return;
     344        //user cancelled, do nothing.
    217345
    218         if (result.hasChanges) {
     346        JoinAreasResult result = joinAreas(areas);
     347
     348        if (result.hasChanges){
     349
    219350            Main.map.mapView.repaint();
    220351            DataSet ds = Main.main.getCurrentDataSet();
    221352            ds.fireSelectionChanged();
     
    225356    }
    226357
    227358    /**
    228      * Will join two overlapping areas
    229      * @param Way First way/area
    230      * @param Way Second way/area
     359     * This method analyzes multipolygon relationships of given ways and collects addition inner ways to consider.
     360     * @param selectedWays the selected ways
     361     * @return list of polygons, or null if too complex relation encountered.
    231362     */
    232     private JoinAreasResult joinAreas(Way a, Way b) {
     363    private List<ComplexPolygon> collectAreas(List<Way> selectedWays){
    233364
    234         JoinAreasResult result = new JoinAreasResult();
    235         result.hasChanges = false;
     365        List<ComplexPolygon> result = new ArrayList<ComplexPolygon>();
    236366
    237         // Fix self-overlapping first or other errors
    238         boolean same = a.equals(b);
    239         if(!same) {
    240             int i = 0;
     367        //prepare the lists, to minimize memory allocation.
     368        List<Way> outerWays = new ArrayList<Way>();
     369        List<Way> innerWays = new ArrayList<Way>();
    241370
    242             //join each area with itself, fixing self-crossings.
    243             JoinAreasResult resultA = joinAreas(a, a);
    244             JoinAreasResult resultB = joinAreas(b, b);
     371        Set<Way> processedOuterWays = new LinkedHashSet<Way>();
     372        Set<Way> processedInnerWays = new LinkedHashSet<Way>();
    245373
    246             if (resultA.mergeSuccessful) {
    247                 a = resultA.outerWay;
    248                 ++i;
     374        for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
     375            if (r.isDeleted() ||
     376                    r.get("type") == null ||
     377                    !r.get("type").equalsIgnoreCase("multipolygon")) {
     378                continue;
    249379            }
    250             if(resultB.mergeSuccessful) {
    251                 b = resultB.outerWay;
    252                 ++i;
     380
     381            boolean hasKnownOuter = false;
     382            outerWays.clear();
     383            innerWays.clear();
     384
     385            for (RelationMember rm : r.getMembers()) {
     386                if (rm.getRole().equalsIgnoreCase("outer")){
     387                    outerWays.add(rm.getWay());
     388                    hasKnownOuter |= selectedWays.contains(rm.getWay());
     389                }
     390                else if (rm.getRole().equalsIgnoreCase("inner")){
     391                    innerWays.add(rm.getWay());
     392                }
    253393            }
    254394
    255             result.hasChanges = i > 0;
    256             cmdsCount = i;
     395            if (!hasKnownOuter) {
     396                continue;
     397            }
     398
     399            if (outerWays.size() > 1){
     400                JOptionPane.showMessageDialog(Main.parent, tr("Sorry. Cannot handle multipolygon relations with multiple outer ways."));
     401                return null;
     402            }
     403
     404            Way outerWay = outerWays.get(0);
     405
     406            //retain only selected inner ways
     407            innerWays.retainAll(selectedWays);
     408
     409            if (processedOuterWays.contains(outerWay)){
     410                JOptionPane.showMessageDialog(Main.parent, tr("Sorry. Cannot handle way that is outer in multiple multipolygon relations."));
     411                return null;
     412            }
     413
     414            if (processedInnerWays.contains(outerWay)){
     415                JOptionPane.showMessageDialog(Main.parent, tr("Sorry. Cannot handle way that is both inner and outer in multipolygon relations."));
     416                return null;
     417            }
     418
     419            for(Way way:innerWays)
     420            {
     421                if (processedOuterWays.contains(way)){
     422                    JOptionPane.showMessageDialog(Main.parent, tr("Sorry. Cannot handle way that is both inner and outer in multipolygon relations."));
     423                    return null;
     424                }
     425
     426                if (processedInnerWays.contains(way)){
     427                    JOptionPane.showMessageDialog(Main.parent, tr("Sorry. Cannot handle way that is inner in multiple multipolygon relations."));
     428                    return null;
     429                }
     430            }
     431
     432            processedOuterWays.add(outerWay);
     433            processedInnerWays.addAll(innerWays);
     434
     435            ComplexPolygon pol = new ComplexPolygon(outerWay);
     436            pol.innerWays.addAll(innerWays);
     437
     438            result.add(pol);
    257439        }
    258440
    259         ArrayList<Node> nodes = addIntersections(a, b);
     441        //add remaining ways, not in relations
     442        for(Way way: selectedWays){
     443            if (processedOuterWays.contains(way) || processedInnerWays.contains(way)) {
     444                continue;
     445            }
    260446
     447            result.add(new ComplexPolygon(way));
     448        }
     449
     450        return result;
     451    }
     452
     453    /**
     454     * Tests if the areas have some intersections to join.
     455     * @param areas
     456     * @return
     457     */
     458    private boolean testJoin(List<ComplexPolygon> areas) {
     459        List<Way> allStartingWays = new ArrayList<Way>();
     460
     461        for(ComplexPolygon area: areas)
     462        {
     463            allStartingWays.add(area.outerWay);
     464            allStartingWays.addAll(area.innerWays);
     465        }
     466
     467        //find intersection points
     468        ArrayList<Node> nodes = addIntersections(allStartingWays, false);
     469        return nodes.size() > 0;
     470    }
     471
     472    /**
     473     * Will join two or more overlapping areas
     474     * @param areas - list of areas to join
     475     * @return new area formed.
     476     */
     477    private JoinAreasResult joinAreas(List<ComplexPolygon> areas) {
     478
     479        JoinAreasResult result = new JoinAreasResult();
     480        result.hasChanges = false;
     481
     482        List<Way> allStartingWays = new ArrayList<Way>();
     483        List<Way> innerStartingWays = new ArrayList<Way>();
     484        List<Way> outerStartingWays = new ArrayList<Way>();
     485
     486        for(ComplexPolygon area: areas)
     487        {
     488            outerStartingWays.add(area.outerWay);
     489            innerStartingWays.addAll(area.innerWays);
     490        }
     491
     492        allStartingWays.addAll(innerStartingWays);
     493        allStartingWays.addAll(outerStartingWays);
     494
     495        //first remove nodes in the same coordinate
     496        boolean removedDuplicates = false;
     497        removedDuplicates |= removeDuplicateNodes(allStartingWays);
     498
     499        if (removedDuplicates)
     500        {
     501            result.hasChanges = true;
     502            commitCommands(marktr("Removed duplicate nodes"));
     503        }
     504
     505        //find intersection points
     506        ArrayList<Node> nodes = addIntersections(allStartingWays, true);
     507
    261508        //no intersections, return.
    262509        if(nodes.size() == 0) return result;
    263510        commitCommands(marktr("Added node on all intersections"));
    264511
     512        ArrayList<RelationRole> relations = new ArrayList<RelationRole>();
     513
    265514        // Remove ways from all relations so ways can be combined/split quietly
    266         ArrayList<RelationRole> relations = removeFromRelations(a);
    267         if(!same) {
    268             relations.addAll(removeFromRelations(b));
     515        for(Way way : allStartingWays)
     516        {
     517            relations.addAll(removeFromRelations(way));
    269518        }
    270519
    271520        // Don't warn now, because it will really look corrupted
    272         boolean warnAboutRelations = relations.size() > 0;
     521        boolean warnAboutRelations = relations.size() > 0 && allStartingWays.size() > 1;
    273522
    274         ArrayList<Way> allWays = splitWaysOnNodes(a, b, nodes);
     523        ArrayList<WayInPath> preparedWays = new ArrayList<WayInPath>();
    275524
     525        for (Way way: outerStartingWays){
     526            ArrayList<Way> splitWays = splitWayOnNodes(way, nodes);
     527            preparedWays.addAll(markWayInsideSide(splitWays, false));
     528        }
     529
     530        for (Way way: innerStartingWays){
     531            ArrayList<Way> splitWays = splitWayOnNodes(way, nodes);
     532            preparedWays.addAll(markWayInsideSide(splitWays, true));
     533        }
     534
    276535        // Find inner ways save them to a list
    277         ArrayList<WayInPath> outerWays = findOuterWays(allWays);
    278         ArrayList<Way> innerWays = findInnerWays(allWays, outerWays);
     536        ArrayList<Way> discardedWays = new ArrayList<Way>();
     537        List<List<WayInPath>> boundryParts = findBoundaryWays(preparedWays, discardedWays);
     538        List<Way> boundaries = joinBoundaries(boundryParts);
    279539
    280         // Join outer ways
    281         Way outerWay = joinOuterWays(outerWays);
     540        List<ComplexPolygon> polygons = findPolygons(boundaries);
    282541
    283         // Fix Multipolygons if there are any
    284         List<Way> newInnerWays = fixMultipolygons(innerWays, outerWay, same);
    285 
    286         // Delete the remaining inner ways
    287         if(innerWays != null && innerWays.size() > 0) {
    288             cmds.add(DeleteCommand.delete(Main.map.mapView.getEditLayer(), innerWays, true));
     542        // Delete the discarded inner ways
     543        if(discardedWays.size() > 0) {
     544            cmds.add(DeleteCommand.delete(Main.map.mapView.getEditLayer(), discardedWays, true));
    289545        }
    290546        commitCommands(marktr("Delete Ways that are not part of an inner multipolygon"));
    291547
    292548        // We can attach our new multipolygon relation and pretend it has always been there
    293         addOwnMultigonRelation(newInnerWays, outerWay, relations);
    294         fixRelations(relations, outerWay);
     549        for(ComplexPolygon pol: polygons)
     550        {
     551            addOwnMultigonRelation(pol.innerWays, pol.outerWay, relations);
     552            fixRelations(relations, pol.outerWay);
     553        }
     554
    295555        commitCommands(marktr("Fix relations"));
    296556
    297         stripTags(newInnerWays);
     557        for(ComplexPolygon pol: polygons)
     558        {
     559            stripTags(pol.innerWays);
     560        }
    298561
    299         makeCommitsOneAction(
    300                 same
    301                 ? marktr("Joined self-overlapping area")
    302                         : marktr("Joined overlapping areas")
    303         );
     562        makeCommitsOneAction(marktr("Joined overlapping areas"));
    304563
    305564        if(warnAboutRelations) {
    306565            JOptionPane.showMessageDialog(Main.parent, tr("Some of the ways were part of relations that have been modified. Please verify no errors have been introduced."));
     
    308567
    309568        result.hasChanges = true;
    310569        result.mergeSuccessful = true;
    311         result.outerWay = outerWay;
    312         result.innerWays = newInnerWays;
    313 
     570        result.polygons = polygons;
    314571        return result;
    315572    }
    316573
     
    318575     * Checks if tags of two given ways differ, and presents the user a dialog to solve conflicts
    319576     * @param Way First way to check
    320577     * @param Way Second Way to check
    321      * @return boolean True if not all conflicts could be resolved, False if everything's fine
     578     * @return boolean True if all conflicts are resolved, False if conflicts remain.
    322579     */
    323     private boolean checkForTagConflicts(Way a, Way b) {
    324         ArrayList<Way> ways = new ArrayList<Way>();
    325         ways.add(a);
    326         ways.add(b);
     580    private boolean resolveTagConflicts(List<Way> ways) {
     581        if (ways.size() < 2)
     582            return true;
    327583
    328         // FIXME: This is mostly copied and pasted from CombineWayAction.java and one day should be moved into tools
    329         // We have TagCollection handling for that now - use it here as well
    330         Map<String, Set<String>> props = new TreeMap<String, Set<String>>();
    331         for (Way w : ways) {
    332             for (String key: w.keySet()) {
    333                 if (!props.containsKey(key)) {
    334                     props.put(key, new TreeSet<String>());
    335                 }
    336                 props.get(key).add(w.get(key));
    337             }
     584        //mostly copied from CombineWayAction.java.
     585        TagCollection wayTags = TagCollection.unionOfAllPrimitives(ways);
     586        TagCollection completeWayTags = new TagCollection(wayTags);
     587        combineTigerTags(completeWayTags);
     588        normalizeTagCollectionBeforeEditing(completeWayTags, ways);
     589        TagCollection tagsToEdit = new TagCollection(completeWayTags);
     590        completeTagCollectionForEditing(tagsToEdit);
     591
     592        CombinePrimitiveResolverDialog dialog = CombinePrimitiveResolverDialog.getInstance();
     593        dialog.getTagConflictResolverModel().populate(tagsToEdit, completeWayTags.getKeysWithMultipleValues());
     594        dialog.setTargetPrimitive(ways.get(0));
     595        Set<Relation> parentRelations = CombineWayAction.getParentRelations(ways);
     596        dialog.getRelationMemberConflictResolverModel().populate(
     597                parentRelations,
     598                ways
     599        );
     600        dialog.prepareDefaultDecisions();
     601
     602        // resolve tag conflicts if necessary
     603        //
     604        if (!completeWayTags.isApplicableToPrimitive() || !parentRelations.isEmpty()) {
     605            dialog.setVisible(true);
     606            if (dialog.isCancelled())
     607                return false;
    338608        }
    339609
    340         Way ax = new Way(a);
    341         Way bx = new Way(b);
     610        for(Way way: ways)
     611        {
     612            dialog.setTargetPrimitive(way);
     613            cmds.addAll(dialog.buildResolutionCommands());
     614        }
    342615
    343         Map<String, JComboBox> components = new HashMap<String, JComboBox>();
    344         JPanel p = new JPanel(new GridBagLayout());
    345         for (Entry<String, Set<String>> e : props.entrySet()) {
    346             if (TigerUtils.isTigerTag(e.getKey())) {
    347                 String combined = TigerUtils.combineTags(e.getKey(), e.getValue());
    348                 ax.put(e.getKey(), combined);
    349                 bx.put(e.getKey(), combined);
    350             } else if (e.getValue().size() > 1) {
    351                 if("created_by".equals(e.getKey()))
    352                 {
    353                     ax.remove("created_by");
    354                     bx.remove("created_by");
    355                 } else {
    356                     JComboBox c = new JComboBox(e.getValue().toArray());
    357                     c.setEditable(true);
    358                     p.add(new JLabel(e.getKey()), GBC.std());
    359                     p.add(Box.createHorizontalStrut(10), GBC.std());
    360                     p.add(c, GBC.eol());
    361                     components.put(e.getKey(), c);
     616        commitCommands(marktr("Fix tag conflicts"));
     617        return true;
     618    }
     619
     620
     621    /**
     622     * This method removes duplicate points (if any) from the input way.
     623     * @param way the way to process
     624     * @return true if any changes where made
     625     */
     626    private boolean removeDuplicateNodes(List<Way> ways)
     627    {
     628        //TODO: maybe join nodes with JoinNodesAction, rather than reconnect the ways.
     629
     630        Map<Node, Node> nodeMap = new TreeMap<Node, Node>(new NodePositionComparator());
     631        int totalNodesRemoved = 0;
     632
     633        for(Way way:ways)
     634        {
     635            if (way.getNodes().size() < 2) {
     636                continue;
     637            }
     638
     639            int nodesRemoved = 0;
     640            List<Node> newNodes = new ArrayList<Node>();
     641            Node prevNode = null;
     642
     643            for(Node node: way.getNodes())
     644            {
     645                if (!nodeMap.containsKey(node)){
     646                    //new node
     647                    nodeMap.put(node, node);
     648
     649                    //avoid duplicate nodes
     650                    if (prevNode != node)
     651                    {
     652                        newNodes.add(node);
     653                    }
     654                    else
     655                    {
     656                        nodesRemoved ++;
     657                    }
    362658                }
    363             } else {
    364                 String val = e.getValue().iterator().next();
    365                 ax.put(e.getKey(), val);
    366                 bx.put(e.getKey(), val);
     659                else{
     660                    //node with same coordinates already exists, substitute with existing node
     661                    Node representator = nodeMap.get(node);
     662
     663                    if (representator != node){
     664                        nodesRemoved ++;
     665                    }
     666
     667                    //avoid duplicate node
     668                    if (prevNode != representator)
     669                    {
     670                        newNodes.add(representator);
     671                    }
     672                }
     673
     674                prevNode = node;
    367675            }
    368         }
    369676
    370         if (components.isEmpty())
    371             return false; // No conflicts found
     677            if (nodesRemoved > 0)
     678            {
    372679
    373         ExtendedDialog ed = new ExtendedDialog(Main.parent,
    374                 tr("Enter values for all conflicts."),
    375                 new String[] {tr("Solve Conflicts"), tr("Cancel")});
    376         ed.setButtonIcons(new String[] {"dialogs/conflict.png", "cancel.png"});
    377         ed.setContent(p);
    378         ed.showDialog();
     680                if (newNodes.size() == 1) {//all nodes in the same coordinate - add one more node, to have closed way.
     681                    newNodes.add(newNodes.get(0));
     682                }
    379683
    380         if (ed.getValue() != 1) return true; // user cancel, unresolvable conflicts
    381 
    382         for (Entry<String, JComboBox> e : components.entrySet()) {
    383             String val = e.getValue().getEditor().getItem().toString();
    384             ax.put(e.getKey(), val);
    385             bx.put(e.getKey(), val);
     684                Way newWay=new Way(way);
     685                newWay.setNodes(newNodes);
     686                cmds.add(new ChangeCommand(way, newWay));
     687                totalNodesRemoved += nodesRemoved;
     688            }
    386689        }
    387690
    388         cmds.add(new ChangeCommand(a, ax));
    389         cmds.add(new ChangeCommand(b, bx));
    390         commitCommands(marktr("Fix tag conflicts"));
    391         return false;
     691        return totalNodesRemoved > 0;
    392692    }
    393693
     694
     695
    394696    /**
    395      * Will find all intersection and add nodes there for two given ways
    396      * @param Way First way
    397      * @param Way Second way
    398      * @return ArrayList<OsmPrimitive> List of new nodes
     697     * Will find all intersection and add nodes there for list of given ways. Handles self-intersections too.
     698     * And make commands to add the intersection points to ways.
     699     * @param List<Way> - a list of ways to test
     700     * @return ArrayList<Node> List of new nodes
     701     * Prerequisite: no two nodes have the same coordinates.
    399702     */
    400     private ArrayList<Node> addIntersections(Way a, Way b) {
    401         boolean same = a.equals(b);
    402         int nodesSizeA = a.getNodesCount();
    403         int nodesSizeB = b.getNodesCount();
     703    private ArrayList<Node> addIntersections(List<Way> ways, boolean execute) {
     704        //TODO: this is a bit slow - O( (number of nodes)^2 + numberOfIntersections * numberOfNodes )
    404705
    405         ArrayList<Node> nodes = new ArrayList<Node>();
    406         ArrayList<NodeToSegs> nodesA = new ArrayList<NodeToSegs>();
    407         ArrayList<NodeToSegs> nodesB = new ArrayList<NodeToSegs>();
     706        //stupid java, cannot instantiate array of generic classes..
     707        @SuppressWarnings("unchecked")
     708        ArrayList<Node>[] newNodes = new ArrayList[ways.size()];
     709        boolean[] changedWays = new boolean[ways.size()];
    408710
    409         for (int i = (same ? 1 : 0); i < nodesSizeA - 1; i++) {
    410             for (int j = (same ? i + 2 : 0); j < nodesSizeB - 1; j++) {
    411                 // Avoid re-adding nodes that already exist on (some) intersections
    412                 if(a.getNode(i).equals(b.getNode(j)) || a.getNode(i+1).equals(b.getNode(j)))   {
    413                     nodes.add(b.getNode(j));
    414                     continue;
    415                 } else
    416                     if(a.getNode(i).equals(b.getNode(j+1)) || a.getNode(i+1).equals(b.getNode(j+1))) {
    417                         nodes.add(b.getNode(j+1));
    418                         continue;
     711        Set<Node> intersectionNodes = new LinkedHashSet<Node>();
     712
     713        for (int pos = 0; pos < ways.size(); pos ++)
     714        {
     715            newNodes[pos] = new ArrayList<Node>(ways.get(pos).getNodes());
     716            changedWays[pos] = false;
     717        }
     718
     719        //iterate over all segment pairs and introduce the intersections
     720
     721        Comparator<Node> coordsComparator = new NodePositionComparator();
     722
     723        int seg1Way = 0;
     724        int seg1Pos = -1;
     725
     726        while (true)
     727        {
     728            //advance to next segment
     729            seg1Pos++;
     730            if (seg1Pos > newNodes[seg1Way].size() - 2)
     731            {
     732                seg1Way++;
     733                seg1Pos = 0;
     734
     735                if (seg1Way == ways.size()) { //finished
     736                    break;
     737                }
     738            }
     739
     740
     741            //iterate over secondary segment
     742
     743            int seg2Way = seg1Way;
     744            int seg2Pos = seg1Pos + 1;//skip the adjacent segment
     745
     746            while (true)
     747            {
     748
     749                //advance to next segment
     750                seg2Pos++;
     751                if (seg2Pos > newNodes[seg2Way].size() - 2)
     752                {
     753                    seg2Way++;
     754                    seg2Pos = 0;
     755
     756                    if (seg2Way == ways.size()) { //finished
     757                        break;
    419758                    }
    420                 LatLon intersection = getLineLineIntersection(
    421                         a.getNode(i)  .getEastNorth().east(), a.getNode(i)  .getEastNorth().north(),
    422                         a.getNode(i+1).getEastNorth().east(), a.getNode(i+1).getEastNorth().north(),
    423                         b.getNode(j)  .getEastNorth().east(), b.getNode(j)  .getEastNorth().north(),
    424                         b.getNode(j+1).getEastNorth().east(), b.getNode(j+1).getEastNorth().north());
    425                 if(intersection == null) {
    426                     continue;
    427759                }
    428760
    429                 // Create the node. Adding them to the ways must be delayed because we still loop over them
    430                 Node n = new Node(intersection);
    431                 cmds.add(new AddCommand(n));
    432                 nodes.add(n);
    433                 // The distance is needed to sort and add the nodes in direction of the way
    434                 nodesA.add(new NodeToSegs(i,  n, a.getNode(i).getCoor()));
    435                 if(same) {
    436                     nodesA.add(new NodeToSegs(j,  n, a.getNode(j).getCoor()));
    437                 } else {
    438                     nodesB.add(new NodeToSegs(j,  n, b.getNode(j).getCoor()));
     761                //need to get them again every time, because other segments may be changed
     762                Node seg1Node1 = newNodes[seg1Way].get(seg1Pos);
     763                Node seg1Node2 = newNodes[seg1Way].get(seg1Pos + 1);
     764                Node seg2Node1 = newNodes[seg2Way].get(seg2Pos);
     765                Node seg2Node2 = newNodes[seg2Way].get(seg2Pos + 1);
     766
     767                int commonCount = 0;
     768                //test if we have common nodes to add.
     769                if (seg1Node1 == seg2Node1 || seg1Node1 == seg2Node2)
     770                {
     771                    commonCount ++;
     772
     773                    if (seg1Way == seg2Way &&
     774                            seg1Pos == 0 &&
     775                            seg2Pos == newNodes[seg2Way].size() -2)
     776                    {
     777                        //do not add - this is first and last segment of the same way.
     778                    }
     779                    else
     780                    {
     781                        intersectionNodes.add(seg1Node1);
     782                    }
    439783                }
     784
     785                if (seg1Node2 == seg2Node1 || seg1Node2 == seg2Node2)
     786                {
     787                    commonCount ++;
     788
     789                    intersectionNodes.add(seg1Node2);
     790                }
     791
     792                //no common nodes - find intersection
     793                if (commonCount == 0)
     794                {
     795                    LatLon intersection = getLineLineIntersection(
     796                            seg1Node1.getEastNorth().east(), seg1Node1.getEastNorth().north(),
     797                            seg1Node2.getEastNorth().east(), seg1Node2.getEastNorth().north(),
     798                            seg2Node1.getEastNorth().east(), seg2Node1.getEastNorth().north(),
     799                            seg2Node2.getEastNorth().east(), seg2Node2.getEastNorth().north());
     800
     801                    if (intersection != null)
     802                    {
     803                        Node newNode = new Node(intersection);
     804                        Node intNode = newNode;
     805                        boolean insertInSeg1 = false;
     806                        boolean insertInSeg2 = false;
     807
     808                        //find if the intersection point is at end point of one of the segments, if so use that point
     809
     810                        //segment 1
     811                        if (coordsComparator.compare(newNode, seg1Node1) == 0) {
     812                            intNode = seg1Node1;
     813                        } else if (coordsComparator.compare(newNode, seg1Node2) == 0) {
     814                            intNode = seg1Node2;
     815                        } else {
     816                            insertInSeg1 = true;
     817                        }
     818
     819                        //segment 2
     820                        if (coordsComparator.compare(newNode, seg2Node1) == 0) {
     821                            intNode = seg2Node1;
     822                        } else if (coordsComparator.compare(newNode, seg2Node2) == 0) {
     823                            intNode = seg2Node2;
     824                        } else {
     825                            insertInSeg2 = true;
     826                        }
     827
     828                        if (insertInSeg1)
     829                        {
     830                            newNodes[seg1Way].add(seg1Pos +1, intNode);
     831                            changedWays[seg1Way] = true;
     832
     833                            //fix seg2 position, as indexes have changed, seg2Pos is always bigger than seg1Pos on the same segment.
     834                            if (seg2Way == seg1Way) {
     835                                seg2Pos ++;
     836                            }
     837                        }
     838
     839                        if (insertInSeg2){
     840                            newNodes[seg2Way].add(seg2Pos +1, intNode);
     841                            changedWays[seg2Way] = true;
     842
     843                            //Do not need to compare again to already split segment
     844                            seg2Pos ++;
     845                        }
     846
     847                        intersectionNodes.add(intNode);
     848
     849                        if (intNode == newNode)
     850                        {
     851                            cmds.add(new AddCommand(intNode));
     852                        }
     853                    }
     854                }
    440855            }
    441856        }
    442857
    443         addNodesToWay(a, nodesA);
    444         if(!same) {
    445             addNodesToWay(b, nodesB);
     858        if (execute){
     859            for (int pos = 0; pos < ways.size(); pos ++)
     860            {
     861                if (changedWays[pos] == false) {
     862                    continue;
     863                }
     864
     865                Way way = ways.get(pos);
     866                Way newWay = new Way(way);
     867                newWay.setNodes(newNodes[pos]);
     868
     869                cmds.add(new ChangeCommand(way, newWay));
     870            }
    446871        }
    447872
    448         return nodes;
     873        return new ArrayList<Node>(intersectionNodes);
    449874    }
    450875
    451876    /**
     
    477902        ));
    478903    }
    479904
    480     /**
    481      * Inserts given nodes with positions into the given ways
    482      * @param Way The way to insert the nodes into
    483      * @param Collection<NodeToSegs> The list of nodes with positions to insert
    484      */
    485     private void addNodesToWay(Way a, ArrayList<NodeToSegs> nodes) {
    486         if(nodes.size() == 0)
    487             return;
    488         Way ax=new Way(a);
    489         Collections.sort(nodes);
    490905
    491         int numOfAdds = 1;
    492         for(NodeToSegs n : nodes) {
    493             ax.addNode(n.pos + numOfAdds, n.n);
    494             numOfAdds++;
    495         }
    496906
    497         cmds.add(new ChangeCommand(a, ax));
    498     }
    499 
    500907    /**
    501908     * Commits the command list with a description
    502909     * @param String The description of what the commands do
     
    518925        cmdsCount++;
    519926    }
    520927
     928
    521929    /**
    522      * Removes a given OsmPrimitive from all relations
    523      * @param OsmPrimitive Element to remove from all relations
    524      * @return ArrayList<RelationRole> List of relations with roles the primitives was part of
     930     * This method analyzes the way and assigns each part what direction polygon "inside" is.
     931     * @param parts the split parts of the way
     932     * @param isInner - if true, reverts the direction (for multipolygon islands)
     933     * @return list of parts, marked with the inside orientation.
    525934     */
    526     private ArrayList<RelationRole> removeFromRelations(OsmPrimitive osm) {
    527         ArrayList<RelationRole> result = new ArrayList<RelationRole>();
    528         for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
    529             if (r.isDeleted()) {
    530                 continue;
     935    private ArrayList<WayInPath> markWayInsideSide(List<Way> parts, boolean isInner){
     936
     937        ArrayList<WayInPath> result = new ArrayList<WayInPath>();
     938
     939        //prepare prev and next maps
     940        Map<Way, Way> nextWayMap = new HashMap<Way, Way>();
     941        Map<Way, Way> prevWayMap = new HashMap<Way, Way>();
     942
     943        for (int pos = 0; pos < parts.size(); pos ++){
     944
     945            if (!parts.get(pos).lastNode().equals(parts.get((pos + 1) % parts.size()).firstNode()))
     946                throw new RuntimeException("Way not circular");
     947
     948            nextWayMap.put(parts.get(pos), parts.get((pos + 1) % parts.size()));
     949            prevWayMap.put(parts.get(pos), parts.get((pos + parts.size() - 1) % parts.size()));
     950        }
     951
     952        //find the node with minimum y - it's guaranteed to be outer. (What about the south pole?)
     953        Way topWay = null;
     954        Node topNode = null;
     955        int topIndex = 0;
     956        double minY = Double.POSITIVE_INFINITY;
     957
     958        for(Way way: parts) {
     959            for (int pos = 0; pos < way.getNodesCount(); pos ++){
     960                Node node = way.getNode(pos);
     961
     962                if (node.getEastNorth().getY() < minY){
     963                    minY = node.getEastNorth().getY();
     964                    topWay = way;
     965                    topNode = node;
     966                    topIndex = pos;
     967                }
    531968            }
    532             for (RelationMember rm : r.getMembers()) {
    533                 if (rm.getMember() != osm) {
    534                     continue;
     969        }
     970
     971        //get the upper way and it's orientation.
     972
     973        boolean wayClockwise; // orientation of the top way.
     974
     975        if (topNode.equals(topWay.firstNode()) || topNode.equals(topWay.lastNode()))
     976        {
     977            Node headNode = null; // the node at junction
     978            Node prevNode = null; // last node from previous path
     979            wayClockwise = false;
     980
     981            //node is in split point - find the outermost way from this point
     982
     983            headNode = topNode;
     984            //make a fake node that is downwards from head node (smaller Y). It will be a division point between paths.
     985            prevNode = new Node(new EastNorth(headNode.getEastNorth().getX(), headNode.getEastNorth().getY() - 1e5));
     986
     987            topWay = null;
     988            wayClockwise = false;
     989            Node bestWayNextNode = null;
     990
     991            for(Way way: parts)
     992            {
     993                if (way.firstNode().equals(headNode))
     994                {
     995                    Node nextNode = way.getNode(1);
     996
     997                    if (topWay == null || !isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode))
     998                    {
     999                        //the new way is better
     1000                        topWay = way;
     1001                        wayClockwise = true;
     1002                        bestWayNextNode = nextNode;
     1003                    }
    5351004                }
    5361005
    537                 Relation newRel = new Relation(r);
    538                 List<RelationMember> members = newRel.getMembers();
    539                 members.remove(rm);
    540                 newRel.setMembers(members);
     1006                if (way.lastNode().equals(headNode))
     1007                {
     1008                    //end adjacent to headNode
     1009                    Node nextNode = way.getNode(way.getNodesCount() - 2);
    5411010
    542                 cmds.add(new ChangeCommand(r, newRel));
    543                 RelationRole saverel =  new RelationRole(r, rm.getRole());
    544                 if(!result.contains(saverel)) {
    545                     result.add(saverel);
     1011                    if (topWay == null || !isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode))
     1012                    {
     1013                        //the new way is better
     1014                        topWay = way;
     1015                        wayClockwise = false;
     1016                        bestWayNextNode = nextNode;
     1017                    }
    5461018                }
     1019            }
     1020        }
     1021        else
     1022        {
     1023            //node is inside way - pick the clockwise going end.
     1024            Node prev = topWay.getNode(topIndex - 1);
     1025            Node next = topWay.getNode(topIndex + 1);
     1026
     1027            //there will be no parallel segments in the middle of way, so all fine.
     1028            wayClockwise = angleIsClockwise(prev, topNode, next);
     1029        }
     1030
     1031        Way curWay = topWay;
     1032        boolean curWayInsideToTheRight = wayClockwise ^ isInner;
     1033
     1034        //iterate till full circle is reached
     1035        while (true){
     1036
     1037            //add cur way
     1038            WayInPath resultWay = new WayInPath(curWay, curWayInsideToTheRight);
     1039            result.add(resultWay);
     1040
     1041            //process next way
     1042            Way nextWay = nextWayMap.get(curWay);
     1043            Node prevNode = curWay.getNode(curWay.getNodesCount() - 2);
     1044            Node headNode = curWay.lastNode();
     1045            Node nextNode = nextWay.getNode(1);
     1046
     1047            if (nextWay == topWay)
     1048            {
     1049                //full loop traversed - all done.
    5471050                break;
    5481051            }
     1052
     1053
     1054            //find intersecting segments
     1055            // the intersections will look like this:
     1056            //
     1057            //                       ^
     1058            //                       |
     1059            //                       X wayBNode
     1060            //                       |
     1061            //                  wayB |
     1062            //                       |
     1063            //             curWay    |       nextWay
     1064            //----X----------------->X----------------------X---->
     1065            //    prevNode           ^headNode              nextNode
     1066            //                       |
     1067            //                       |
     1068            //                  wayA |
     1069            //                       |
     1070            //                       X wayANode
     1071            //                       |
     1072
     1073            int intersectionCount = 0;
     1074
     1075            for (Way wayA: parts){
     1076
     1077                if (wayA == curWay){
     1078                    continue;
     1079                }
     1080
     1081                if (wayA.lastNode().equals(headNode)){
     1082
     1083                    Way wayB = nextWayMap.get(wayA);
     1084
     1085                    //test if wayA is opposite wayB relative to curWay and nextWay
     1086
     1087                    Node wayANode = wayA.getNode(wayA.getNodesCount() - 2);
     1088                    Node wayBNode = wayB.getNode(1);
     1089
     1090                    boolean wayAToTheRight = isToTheRightSideOfLine(prevNode, headNode, nextNode, wayANode);
     1091                    boolean wayBToTheRight = isToTheRightSideOfLine(prevNode, headNode, nextNode, wayBNode);
     1092
     1093                    if (wayAToTheRight != wayBToTheRight){
     1094                        intersectionCount ++;
     1095                    }
     1096                }
     1097            }
     1098
     1099            //if odd number of crossings, invert orientation
     1100            if (intersectionCount % 2 == 1){
     1101                curWayInsideToTheRight = !curWayInsideToTheRight;
     1102            }
     1103
     1104            curWay = nextWay;
    5491105        }
    5501106
    551         commitCommands(marktr("Removed Element from Relations"));
    5521107        return result;
    5531108    }
    5541109
    5551110    /**
    556      * This method splits ways into smaller parts, using the prepared nodes list as split points.
    557      * Uses SplitWayAction.splitWay for the heavy lifting.
     1111     * This is a method splits way into smaller parts, using the prepared nodes list as split points.
     1112     * Uses  SplitWayAction.splitWay for the heavy lifting.
    5581113     * @return list of split ways (or original ways if no splitting is done).
    5591114     */
    560     private ArrayList<Way> splitWaysOnNodes(Way a, Way b, Collection<Node> nodes) {
     1115    private ArrayList<Way> splitWayOnNodes(Way way, Collection<Node> nodes) {
    5611116
    5621117        ArrayList<Way> result = new ArrayList<Way>();
    563         List<Way> ways = new ArrayList<Way>();
    564         ways.add(a);
    565         ways.add(b);
     1118        List<List<Node>> chunks = buildNodeChunks(way, nodes);
    5661119
    567         for (Way way: ways) {
    568             List<List<Node>> chunks = buildNodeChunks(way, nodes);
     1120        if (chunks.size() > 1)
     1121        {
    5691122            SplitWayResult split = SplitWayAction.splitWay(Main.map.mapView.getEditLayer(), way, chunks, Collections.<OsmPrimitive>emptyList());
    5701123
    5711124            //execute the command, we need the results
    572             Main.main.undoRedo.add(split.getCommand());
    573             cmdsCount ++;
     1125            cmds.add(split.getCommand());
     1126            commitCommands(marktr("Split ways into fragments"));
    5741127
    5751128            result.add(split.getOriginalWay());
    5761129            result.addAll(split.getNewWays());
     1130        } else {
     1131            //nothing to split
     1132            result.add(way);
    5771133        }
    5781134
    5791135        return result;
    5801136    }
    5811137
     1138
    5821139    /**
    5831140     * Simple chunking version. Does not care about circular ways and result being proper, we will glue it all back together later on.
    5841141     * @param way the way to chunk
    5851142     * @param splitNodes the places where to cut.
    586      * @return list of node segments to produce.
     1143     * @return list of node paths to produce.
    5871144     */
    5881145    private List<List<Node>> buildNodeChunks(Way way, Collection<Node> splitNodes)
    5891146    {
     
    6071164        return result;
    6081165    }
    6091166
    610     /**
    611      * Returns all nodes for given ways
    612      * @param Collection<Way> The list of ways which nodes are to be returned
    613      * @return Collection<Node> The list of nodes the ways contain
    614      */
    615     private Collection<Node> getNodesFromWays(Collection<Way> ways) {
    616         Collection<Node> allNodes = new ArrayList<Node>();
    617         for(Way w: ways) {
    618             allNodes.addAll(w.getNodes());
     1167
     1168    private List<ComplexPolygon> findPolygons(Collection<Way> boundaryWays) {
     1169
     1170        List<PolygonLevel> list = findOuterWaysImpl(0, boundaryWays);
     1171        List<ComplexPolygon> result = new ArrayList<ComplexPolygon>();
     1172
     1173        //take every other level
     1174        for(PolygonLevel pol: list){
     1175            if (pol.level %2 == 0){
     1176                result.add(pol.pol);
     1177            }
    6191178        }
    620         return allNodes;
     1179
     1180        return result;
    6211181    }
    6221182
    6231183    /**
    624      * Gets all inner ways given all ways and outer ways.
    625      * @param multigonWays
    626      * @param outerWays
    627      * @return list of inner ways.
     1184     * Collects outer way and corresponding inner ways from all boundaries.
     1185     * @param boundaryWays
     1186     * @return the outermostWay.
    6281187     */
    629     private ArrayList<Way> findInnerWays(Collection<Way> multigonWays, Collection<WayInPath> outerWays) {
    630         ArrayList<Way> innerWays = new ArrayList<Way>();
    631         Set<Way> outerSet = new HashSet<Way>();
     1188    private List<PolygonLevel> findOuterWaysImpl(int level, Collection<Way> boundaryWays) {
    6321189
    633         for(WayInPath w: outerWays) {
    634             outerSet.add(w.way);
    635         }
     1190        //TODO: bad performance for deep nestings...
     1191        List<PolygonLevel> result = new ArrayList<PolygonLevel>();
    6361192
    637         for(Way way: multigonWays) {
    638             if (!outerSet.contains(way)) {
    639                 innerWays.add(way);
     1193        for(Way outerWay: boundaryWays){
     1194
     1195            boolean outerGood = true;
     1196            List<Way> innerCandidates = new ArrayList<Way>();
     1197
     1198            for (Way innerWay: boundaryWays)
     1199            {
     1200                if (innerWay == outerWay) {
     1201                    continue;
     1202                }
     1203
     1204                if (wayInsideWay(outerWay, innerWay))
     1205                {
     1206                    outerGood = false;
     1207                    break;
     1208                } else if (wayInsideWay(innerWay, outerWay)){
     1209                    innerCandidates.add(innerWay);
     1210                }
    6401211            }
     1212
     1213            if (!outerGood)
     1214            {
     1215                continue;
     1216            }
     1217
     1218            //add new outer polygon
     1219            ComplexPolygon pol = new ComplexPolygon(outerWay);
     1220            PolygonLevel polLev = new PolygonLevel(pol, level);
     1221
     1222            //process inner ways
     1223            if (innerCandidates.size() > 0)
     1224            {
     1225                List<PolygonLevel> innerList = findOuterWaysImpl(level + 1, innerCandidates);
     1226                result.addAll(innerList);
     1227
     1228                for (PolygonLevel pl: innerList)
     1229                {
     1230                    if (pl.level == level + 1)
     1231                    {
     1232                        pol.innerWays.add(pl.pol.outerWay);
     1233                    }
     1234                }
     1235            }
     1236
     1237            result.add(polLev);
    6411238        }
    6421239
    643         return innerWays;
     1240        return result;
    6441241    }
    6451242
    6461243
     1244
    6471245    /**
    648      * Finds all ways for a given list of Ways that form the outer hull.
    649      * This works by starting with one node and traversing the multigon clockwise, always picking the leftmost path.
    650      * Prerequisites - the ways must not intersect and have common end nodes where they meet.
    651      * @param Collection<Way> A list of (splitted) ways that form a multigon
    652      * @return Collection<Way> A list of ways that form the outer boundary of the multigon.
     1246     * Finds all ways that form inner or outer boundaries.
     1247     * @param Collection<Way> A list of (splitted) ways that form a multigon and share common end nodes on intersections.
     1248     * @param Collection<Way> this list is filled with ways that are to be discarded
     1249     * @return Collection<Collection<Way>> A list of ways that form the outer and inner boundaries of the multigon.
    6531250     */
    654     private static ArrayList<WayInPath> findOuterWays(Collection<Way> multigonWays) {
     1251    public static List<List<WayInPath>> findBoundaryWays(Collection<WayInPath> multigonWays, List<Way> discardedResult)
     1252    {
     1253        //first find all discardable ways, by getting outer shells.
     1254        //this will produce incorrect boundaries in some cases, but second pass will fix it.
    6551255
    656         //find the node with minimum lat - it's guaranteed to be outer. (What about the south pole?)
    657         Way bestWay = null;
    658         Node topNode = null;
    659         int topIndex = 0;
    660         double minLat = Double.POSITIVE_INFINITY;
     1256        List<WayInPath> discardedWays = new ArrayList<WayInPath>();
     1257        Set<WayInPath> processedWays = new HashSet<WayInPath>();
     1258        WayTraverser traverser = new WayTraverser(multigonWays);
    6611259
    662         for(Way way: multigonWays) {
    663             for (int pos = 0; pos < way.getNodesCount(); pos ++) {
    664                 Node node = way.getNode(pos);
    6651260
    666                 if (node.getCoor().lat() < minLat) {
    667                     minLat = node.getCoor().lat();
    668                     bestWay = way;
    669                     topNode = node;
    670                     topIndex = pos;
    671                 }
     1261        for( WayInPath startWay: multigonWays)
     1262        {
     1263            if (processedWays.contains(startWay)) {
     1264                continue;
    6721265            }
    673         }
    6741266
    675         //get two final nodes from best way to mark as starting point and orientation.
    676         Node headNode = null;
    677         Node prevNode = null;
     1267            traverser.startNewWay(startWay);
    6781268
    679         if (topNode.equals(bestWay.firstNode()) || topNode.equals(bestWay.lastNode())) {
    680             //node is in split point
    681             headNode = topNode;
    682             //make a fake node that is downwards from head node (smaller latitude). It will be a division point between paths.
    683             prevNode = new Node(new LatLon(headNode.getCoor().lat() - 1000, headNode.getCoor().lon()));
    684         } else {
    685             //node is inside way - pick the clockwise going end.
    686             Node prev = bestWay.getNode(topIndex - 1);
    687             Node next = bestWay.getNode(topIndex + 1);
     1269            List<WayInPath> boundary = new ArrayList<WayInPath>();
     1270            WayInPath lastWay = startWay;
    6881271
    689             if (angleIsClockwise(prev, topNode, next)) {
    690                 headNode = bestWay.lastNode();
    691                 prevNode = bestWay.getNode(bestWay.getNodesCount() - 2);
     1272            while (true) {
     1273                boundary.add(lastWay);
     1274
     1275                WayInPath bestWay = traverser.advanceNextLeftmostWay();
     1276                boolean wayInsideToTheRight = bestWay == null ? false: traverser.isLastWayInsideToTheRight();
     1277
     1278                if (bestWay == null || processedWays.contains(bestWay) || !wayInsideToTheRight) {
     1279                    //bad segment chain - proceed to discard it
     1280                    lastWay = null;
     1281                    break;
     1282                } else if (boundary.contains(bestWay)){
     1283                    //traversed way found - close the way
     1284                    lastWay = bestWay;
     1285                    break;
     1286                } else {
     1287                    //proceed to next segment
     1288                    lastWay = bestWay;
     1289                }
    6921290            }
    693             else {
    694                 headNode = bestWay.firstNode();
    695                 prevNode = bestWay.getNode(1);
     1291
     1292            if (lastWay != null)
     1293            {
     1294                //way good
     1295                processedWays.addAll(boundary);
     1296
     1297                //remove junk segments at the start
     1298                while (boundary.get(0) != lastWay)
     1299                {
     1300                    discardedWays.add(boundary.get(0));
     1301                    boundary.remove(0);
     1302                }
    6961303            }
     1304            else
     1305            {
     1306                //way bad
     1307                discardedWays.addAll(boundary);
     1308                processedWays.addAll(boundary);
     1309            }
    6971310        }
    6981311
    699         Set<Way> outerWays = new HashSet<Way>();
    700         ArrayList<WayInPath> result = new ArrayList<WayInPath>();
     1312        //now we have removed junk segments, collect the real result ways
    7011313
    702         //iterate till full circle is reached
    703         while (true) {
     1314        traverser.removeWays(discardedWays);
    7041315
    705             bestWay = null;
    706             Node bestWayNextNode = null;
    707             boolean bestWayReverse = false;
     1316        List<List<WayInPath>> result = new ArrayList<List<WayInPath>>();
    7081317
    709             for (Way way: multigonWays) {
    710                 boolean wayReverse;
    711                 Node nextNode;
     1318        while(traverser.hasWays()){
    7121319
    713                 if (way.firstNode().equals(headNode)) {
    714                     //start adjacent to headNode
    715                     nextNode = way.getNode(1);
    716                     wayReverse = false;
     1320            WayInPath startWay = traverser.startNewWay();
     1321            List<WayInPath> boundary = new ArrayList<WayInPath>();
     1322            WayInPath curWay = startWay;
    7171323
    718                     if (nextNode.equals(prevNode)) {
    719                         //this is the path we came from - ignore it.
    720                     } else if (bestWay == null || !isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode)) {
    721                         //the new way is better
    722                         bestWay = way;
    723                         bestWayReverse = wayReverse;
    724                         bestWayNextNode = nextNode;
    725                     }
    726                 }
     1324            do{
     1325                boundary.add(curWay);
     1326                curWay = traverser.advanceNextRightmostWay();
    7271327
    728                 if (way.lastNode().equals(headNode)) {
    729                     //end adjacent to headNode
    730                     nextNode = way.getNode(way.getNodesCount() - 2);
    731                     wayReverse = true;
     1328                //should not happen
     1329                if (curWay == null || !traverser.isLastWayInsideToTheRight())
     1330                    throw new RuntimeException("Join areas internal error.");
    7321331
    733                     if (nextNode.equals(prevNode)) {
    734                         //this is the path we came from - ignore it.
    735                     } else if (bestWay == null || !isToTheRightSideOfLine(prevNode, headNode, bestWayNextNode, nextNode)) {
    736                         //the new way is better
    737                         bestWay = way;
    738                         bestWayReverse = wayReverse;
    739                         bestWayNextNode = nextNode;
    740                     }
    741                 }
    742             }
     1332            } while (curWay != startWay);
    7431333
    744             if (bestWay == null)
    745                 throw new RuntimeException();
    746             else if (outerWays.contains(bestWay)) {
    747                 break; //full circle reached, terminate.
    748             } else {
    749                 //add to outer ways, repeat.
    750                 outerWays.add(bestWay);
    751                 result.add(new WayInPath(bestWay, bestWayReverse));
    752                 headNode = bestWayReverse ? bestWay.firstNode() : bestWay.lastNode();
    753                 prevNode = bestWayReverse ? bestWay.getNode(1) : bestWay.getNode(bestWay.getNodesCount() - 2);
    754             }
     1334            //build result
     1335            traverser.removeWays(boundary);
     1336            result.add(boundary);
    7551337        }
    7561338
     1339        for(WayInPath way:discardedWays){
     1340            discardedResult.add(way.way);
     1341        }
     1342
    7571343        return result;
    7581344    }
    7591345
     1346
    7601347    /**
    7611348     * Tests if given point is to the right side of path consisting of 3 points.
    7621349     * @param lineP1 first point in path
     
    7841371     * @param secondNode second vector end node
    7851372     * @return true if first vector is clockwise before second vector.
    7861373     */
     1374
    7871375    public static boolean angleIsClockwise(Node commonNode, Node firstNode, Node secondNode)
    7881376    {
    789         double dla1 = (firstNode.getCoor().lat() - commonNode.getCoor().lat());
    790         double dla2 = (secondNode.getCoor().lat() - commonNode.getCoor().lat());
    791         double dlo1 = (firstNode.getCoor().lon() - commonNode.getCoor().lon());
    792         double dlo2 = (secondNode.getCoor().lon() - commonNode.getCoor().lon());
     1377        double dy1 = (firstNode.getEastNorth().getY() - commonNode.getEastNorth().getY());
     1378        double dy2 = (secondNode.getEastNorth().getY() - commonNode.getEastNorth().getY());
     1379        double dx1 = (firstNode.getEastNorth().getX() - commonNode.getEastNorth().getX());
     1380        double dx2 = (secondNode.getEastNorth().getX() - commonNode.getEastNorth().getX());
    7931381
    794         return dla1 * dlo2 - dlo1 * dla2 > 0;
     1382        return dy1 * dx2 - dx1 * dy2 > 0;
    7951383    }
    7961384
     1385
    7971386    /**
     1387     * Tests if way is inside other way
     1388     * @param outside
     1389     * @param inside
     1390     * @return
     1391     */
     1392    public static boolean wayInsideWay(Way inside, Way outside)
     1393    {
     1394        for(Node insideNode: inside.getNodes()){
     1395
     1396            if (!outside.getNodes().contains(insideNode))
     1397                //simply test the one node
     1398                return nodeInsidePolygon(insideNode, outside.getNodes());
     1399        }
     1400
     1401        //all nodes shared.
     1402        return false;
     1403    }
     1404
     1405    /**
    7981406     * Tests if point is inside a polygon. The polygon can be self-intersecting. In such case the contains function works in xor-like manner.
    7991407     * @param polygonNodes list of nodes from polygon path.
    8001408     * @param point the point to test
    8011409     * @return true if the point is inside polygon.
    8021410     * FIXME: this should probably be moved to tools..
    8031411     */
    804     public static boolean nodeInsidePolygon(ArrayList<Node> polygonNodes, Node point)
     1412    public static boolean nodeInsidePolygon(Node point, List<Node> polygonNodes)
    8051413    {
    8061414        if (polygonNodes.size() < 3)
    8071415            return false;
     
    8201428            }
    8211429
    8221430            //order points so p1.lat <= p2.lat;
    823             if (newPoint.getCoor().lat() > oldPoint.getCoor().lat())
     1431            if (newPoint.getEastNorth().getY() > oldPoint.getEastNorth().getY())
    8241432            {
    8251433                p1 = oldPoint;
    8261434                p2 = newPoint;
     
    8321440            }
    8331441
    8341442            //test if the line is crossed and if so invert the inside flag.
    835             if ((newPoint.getCoor().lat() < point.getCoor().lat()) == (point.getCoor().lat() <= oldPoint.getCoor().lat())
    836                     && (point.getCoor().lon() - p1.getCoor().lon()) * (p2.getCoor().lat() - p1.getCoor().lat())
    837                     < (p2.getCoor().lon() - p1.getCoor().lon()) * (point.getCoor().lat() - p1.getCoor().lat()))
     1443            if ((newPoint.getEastNorth().getY() < point.getEastNorth().getY()) == (point.getEastNorth().getY() <= oldPoint.getEastNorth().getY())
     1444                    && (point.getEastNorth().getX() - p1.getEastNorth().getX()) * (p2.getEastNorth().getY() - p1.getEastNorth().getY())
     1445                    < (p2.getEastNorth().getX() - p1.getEastNorth().getX()) * (point.getEastNorth().getY() - p1.getEastNorth().getY()))
    8381446            {
    8391447                inside = !inside;
    8401448            }
     
    8451453        return inside;
    8461454    }
    8471455
     1456
    8481457    /**
     1458     * Joins the lists of ways.
     1459     * @param Collection<Way> The list of outer ways that belong to that multigon.
     1460     * @return Way The newly created outer way
     1461     */
     1462    private ArrayList<Way> joinBoundaries(List<List<WayInPath>> outerWays) {
     1463        ArrayList<Way> result = new ArrayList<Way>();
     1464
     1465        for(List<WayInPath> ways: outerWays)
     1466        {
     1467            Way boundary = joinOuterWays(ways);
     1468            result.add(boundary);
     1469        }
     1470
     1471        return result;
     1472    }
     1473
     1474
     1475    /**
    8491476     * Joins the outer ways and deletes all short ways that can't be part of a multipolygon anyway.
    8501477     * @param Collection<Way> The list of outer ways that belong to that multigon.
    8511478     * @return Way The newly created outer way
    8521479     */
    853     private Way joinOuterWays(ArrayList<WayInPath> outerWays) {
     1480    private Way joinOuterWays(List<WayInPath> outerWays) {
    8541481
    8551482        //leave original orientation, if all paths are reverse.
    8561483        boolean allReverse = true;
    857         for(WayInPath way: outerWays) {
    858             allReverse &= way.insideToTheLeft;
     1484        for(WayInPath way: outerWays){
     1485            allReverse &= !way.insideToTheRight;
    8591486        }
    8601487
    861         if (allReverse) {
     1488        if (allReverse){
    8621489            for(WayInPath way: outerWays){
    863                 way.insideToTheLeft = !way.insideToTheLeft;
     1490                way.insideToTheRight = !way.insideToTheRight;
    8641491            }
    8651492        }
    8661493
    8671494        commitCommands(marktr("Join Areas: Remove Short Ways"));
     1495
    8681496        Way joinedWay = joinOrientedWays(outerWays);
    8691497        if (joinedWay != null)
    8701498            return closeWay(joinedWay);
     
    8931521     * @param ArrayList<Way> The list of ways to join and reverse
    8941522     * @return Way The newly created way
    8951523     */
    896     private Way joinOrientedWays(ArrayList<WayInPath> ways) {
    897         if(ways.size() < 2)
    898             return ways.get(0).way;
     1524    private Way joinOrientedWays(List<WayInPath> ways) {
     1525        if(ways.size() < 2) return ways.get(0).way;
    8991526
    9001527        // This will turn ways so all of them point in the same direction and CombineAction won't bug
    9011528        // the user about this.
    9021529
     1530        //TODO: ReverseWay and Combine way are really slow and we use them a lot here. This slows down large joins.
     1531
    9031532        List<Way> actionWays = new ArrayList<Way>(ways.size());
    9041533
    9051534        for(WayInPath way : ways) {
    9061535            actionWays.add(way.way);
    9071536
    908             if (way.insideToTheLeft) {
     1537            if (!way.insideToTheRight)
     1538            {
    9091539                Main.main.getCurrentDataSet().setSelected(way.way);
    9101540                new ReverseWayAction().actionPerformed(null);
    9111541                cmdsCount++;
     
    9201550        return result;
    9211551    }
    9221552
     1553
    9231554    /**
    924      * Joins a list of ways (using CombineWayAction and ReverseWayAction if necessary to quiet the former)
    925      * @param ArrayList<Way> The list of ways to join
    926      * @return Way The newly created way
     1555     * Removes a given OsmPrimitive from all relations
     1556     * @param OsmPrimitive Element to remove from all relations
     1557     * @return ArrayList<RelationRole> List of relations with roles the primitives was part of
    9271558     */
    928     private Way joinWays(ArrayList<Way> ways) {
    929         if(ways.size() < 2)
    930             return ways.get(0);
     1559    private ArrayList<RelationRole> removeFromRelations(OsmPrimitive osm) {
     1560        ArrayList<RelationRole> result = new ArrayList<RelationRole>();
    9311561
    932         // This will turn ways so all of them point in the same direction and CombineAction won't bug
    933         // the user about this.
    934         Way a = null;
    935         for (Way b : ways) {
    936             if(a == null) {
    937                 a = b;
     1562        for (Relation r : Main.main.getCurrentDataSet().getRelations()) {
     1563            if (r.isDeleted()) {
    9381564                continue;
    9391565            }
    940             if(a.getNode(0).equals(b.getNode(0)) ||
    941                     a.getNode(a.getNodesCount()-1).equals(b.getNode(b.getNodesCount()-1))) {
    942                 Main.main.getCurrentDataSet().setSelected(b);
    943                 new ReverseWayAction().actionPerformed(null);
    944                 cmdsCount++;
    945             }
    946             a = b;
    947         }
    948         if ((a = new CombineWayAction().combineWays(ways)) != null) {
    949             cmdsCount++;
    950         }
    951         return a;
    952     }
    953 
    954     /**
    955      * Finds all ways that may be part of a multipolygon relation and removes them from the given list.
    956      * It will automatically combine "good" ways
    957      * @param Collection<Way> The list of inner ways to check
    958      * @param Way The newly created outer way
    959      * @return ArrayList<Way> The List of newly created inner ways
    960      */
    961     private ArrayList<Way> fixMultipolygons(Collection<Way> uninterestingWays, Way outerWay, boolean selfintersect) {
    962         Collection<Node> innerNodes = getNodesFromWays(uninterestingWays);
    963         Collection<Node> outerNodes = outerWay.getNodes();
    964 
    965         // The newly created inner ways. uninterestingWays is passed by reference and therefore modified in-place
    966         ArrayList<Way> newInnerWays = new ArrayList<Way>();
    967 
    968         // Now we need to find all inner ways that contain a remaining node, but no outer nodes
    969         // Remaining nodes are those that contain to more than one way. All nodes that belong to an
    970         // inner multigon part will have at least two ways, so we can use this to find which ways do
    971         // belong to the multigon.
    972         ArrayList<Way> possibleWays = new ArrayList<Way>();
    973         wayIterator: for(Way w : uninterestingWays) {
    974             boolean hasInnerNodes = false;
    975             for(Node n : w.getNodes()) {
    976                 if(outerNodes.contains(n)) {
    977                     if(!selfintersect) { // allow outer point for self intersection
    978                         continue wayIterator;
    979                     }
     1566            for (RelationMember rm : r.getMembers()) {
     1567                if (rm.getMember() != osm) {
     1568                    continue;
    9801569                }
    981                 else if(!hasInnerNodes && innerNodes.contains(n)) {
    982                     hasInnerNodes = true;
    983                 }
    984             }
    985             if(!hasInnerNodes || w.getNodesCount() < 2) {
    986                 continue;
    987             }
    988             possibleWays.add(w);
    989         }
    9901570
    991         // This removes unnecessary ways that might have been added.
    992         removeAlmostAlikeWays(possibleWays);
     1571                Relation newRel = new Relation(r);
     1572                List<RelationMember> members = newRel.getMembers();
     1573                members.remove(rm);
     1574                newRel.setMembers(members);
    9931575
    994         // loop twice
    995         // in k == 0 prefer ways which allow no Y-joining (i.e. which have only 1 solution)
    996         for(int k = 0; k < 2; ++k)
    997         {
    998             // Join all ways that have one start/ending node in common
    999             Way joined = null;
    1000             outerIterator: do {
    1001                 removePartlyUnconnectedWays(possibleWays);
    1002                 joined = null;
    1003                 for(Way w1 : possibleWays) {
    1004                     if(w1.isClosed()) {
    1005                         if(!wayIsCollapsed(w1)) {
    1006                             uninterestingWays.remove(w1);
    1007                             newInnerWays.add(w1);
    1008                         }
    1009                         joined = w1;
    1010                         possibleWays.remove(w1);
    1011                         continue outerIterator;
    1012                     }
    1013                     ArrayList<Way> secondary = new ArrayList<Way>();
    1014                     for(Way w2 : possibleWays) {
    1015                         int i = 0;
    1016                         // w2 cannot be closed, otherwise it would have been removed above
    1017                         if(w1.equals(w2)) {
    1018                             continue;
    1019                         }
    1020                         if(w2.isFirstLastNode(w1.firstNode())) {
    1021                             ++i;
    1022                         }
    1023                         if(w2.isFirstLastNode(w1.lastNode())) {
    1024                             ++i;
    1025                         }
    1026                         if(i == 2) // this way closes w1 - take it!
    1027                         {
    1028                             if(secondary.size() > 0) {
    1029                                 secondary.clear();
    1030                             }
    1031                             secondary.add(w2);
    1032                             break;
    1033                         }
    1034                         else if(i > 0) {
    1035                             secondary.add(w2);
    1036                         }
    1037                     }
    1038                     if(k == 0 ? secondary.size() == 1 : secondary.size() > 0)
    1039                     {
    1040                         ArrayList<Way> joinThem = new ArrayList<Way>();
    1041                         joinThem.add(w1);
    1042                         joinThem.add(secondary.get(0));
    1043                         // Although we joined the ways, we cannot simply assume that they are closed
    1044                         if((joined = joinWays(joinThem)) != null)
    1045                         {
    1046                             uninterestingWays.removeAll(joinThem);
    1047                             possibleWays.removeAll(joinThem);
    1048 
    1049                             //List<Node> nodes = joined.getNodes();
    1050                             // check if we added too much
    1051                             /*for(int i = 1; i < nodes.size()-2; ++i)
    1052                             {
    1053                                 if(nodes.get(i) == nodes.get(nodes.size()-1))
    1054                                     System.out.println("Joining of ways produced unexpecteded result\n");
    1055                             }*/
    1056                             uninterestingWays.add(joined);
    1057                             possibleWays.add(joined);
    1058                             continue outerIterator;
    1059                         }
    1060                     }
     1576                cmds.add(new ChangeCommand(r, newRel));
     1577                RelationRole saverel =  new RelationRole(r, rm.getRole());
     1578                if(!result.contains(saverel)) {
     1579                    result.add(saverel);
    10611580                }
    1062             } while(joined != null);
    1063         }
    1064         return newInnerWays;
    1065     }
    1066 
    1067     /**
    1068      * Removes almost alike ways (= ways that are on top of each other for all nodes)
    1069      * @param ArrayList<Way> the ways to remove almost-duplicates from
    1070      */
    1071     private void removeAlmostAlikeWays(ArrayList<Way> ways) {
    1072         Collection<Way> removables = new ArrayList<Way>();
    1073         outer: for(int i=0; i < ways.size(); i++) {
    1074             Way a = ways.get(i);
    1075             for(int j=i+1; j < ways.size(); j++) {
    1076                 Way b = ways.get(j);
    1077                 List<Node> revNodes = new ArrayList<Node>(b.getNodes());
    1078                 Collections.reverse(revNodes);
    1079                 if(a.getNodes().equals(b.getNodes()) || a.getNodes().equals(revNodes)) {
    1080                     removables.add(a);
    1081                     continue outer;
    1082                 }
     1581                break;
    10831582            }
    10841583        }
    1085         ways.removeAll(removables);
    1086     }
    10871584
    1088     /**
    1089      * Removes ways from the given list whose starting or ending node doesn't
    1090      * connect to other ways from the same list (it's like removing spikes).
    1091      * @param ArrayList<Way> The list of ways to remove "spikes" from
    1092      */
    1093     private void removePartlyUnconnectedWays(ArrayList<Way> ways) {
    1094         List<Way> removables = new ArrayList<Way>();
    1095         for(Way a : ways) {
    1096             if(a.isClosed()) {
    1097                 continue;
    1098             }
    1099             boolean connectedStart = false;
    1100             boolean connectedEnd = false;
    1101             for(Way b : ways) {
    1102                 if(a.equals(b)) {
    1103                     continue;
    1104                 }
    1105                 if(b.isFirstLastNode(a.firstNode())) {
    1106                     connectedStart = true;
    1107                 }
    1108                 if(b.isFirstLastNode(a.lastNode())) {
    1109                     connectedEnd = true;
    1110                 }
    1111             }
    1112             if(!connectedStart || !connectedEnd) {
    1113                 removables.add(a);
    1114             }
    1115         }
    1116         ways.removeAll(removables);
     1585        commitCommands(marktr("Removed Element from Relations"));
     1586        return result;
    11171587    }
    11181588
    1119     /**
    1120      * Checks if a way is collapsed (i.e. looks like <---->)
    1121      * @param Way A *closed* way to check if it is collapsed
    1122      * @return boolean If the closed way is collapsed or not
    1123      */
    1124     private boolean wayIsCollapsed(Way w) {
    1125         if(w.getNodesCount() <= 3) return true;
    11261589
    1127         // If a way contains more than one node twice, it must be collapsed (only start/end node may be the same)
    1128         Way x = new Way(w);
    1129         int count = 0;
    1130         for(Node n : w.getNodes()) {
    1131             x.removeNode(n);
    1132             if(x.containsNode(n)) {
    1133                 count++;
    1134             }
    1135             if(count == 2) return true;
    1136         }
    1137         return false;
    1138     }
    11391590
    11401591    /**
    11411592     * Will add own multipolygon relation to the "previously existing" relations. Fixup is done by fixRelations
     
    12701721    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
    12711722        setEnabled(selection != null && !selection.isEmpty());
    12721723    }
     1724
    12731725}
  • test/unit/actions/JoinAreasActionTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package actions;
     3
     4import org.junit.Assert;
     5import org.junit.Test;
     6import org.openstreetmap.josm.actions.JoinAreasAction;
     7import org.openstreetmap.josm.data.coor.LatLon;
     8import org.openstreetmap.josm.data.osm.Node;
     9
     10
     11public class JoinAreasActionTest {
     12
     13    private Node makeNode(double lat, double lon)
     14    {
     15        Node node = new Node(new LatLon(lat, lon));
     16        return node;
     17    }
     18
     19    @Test
     20    public void testAngleIsClockwise()
     21    {
     22        Assert.assertTrue(JoinAreasAction.angleIsClockwise(makeNode(0,0), makeNode(1,1), makeNode(0,1)));
     23        Assert.assertTrue(JoinAreasAction.angleIsClockwise(makeNode(1,1), makeNode(0,1), makeNode(0,0)));
     24        Assert.assertTrue(!JoinAreasAction.angleIsClockwise(makeNode(1,1), makeNode(0,1), makeNode(1,0)));
     25    }
     26
     27    @Test
     28    public void testisToTheRightSideOfLine()
     29    {
     30        Assert.assertTrue(JoinAreasAction.isToTheRightSideOfLine(makeNode(0,0), makeNode(1,1), makeNode(0,1), makeNode(0, 0.5)));
     31        Assert.assertTrue(!JoinAreasAction.isToTheRightSideOfLine(makeNode(0,0), makeNode(1,1), makeNode(0,1), makeNode(1, 0)));
     32        Assert.assertTrue(!JoinAreasAction.isToTheRightSideOfLine(makeNode(1,1), makeNode(0,1), makeNode(1,0), makeNode(0,0)));
     33        Assert.assertTrue(JoinAreasAction.isToTheRightSideOfLine(makeNode(1,1), makeNode(0,1), makeNode(1,0), makeNode(2, 0)));
     34    }
     35
     36}