@@ -50,7 +50,7 @@ public class BuildingValidator : OsmModelFactory<BuildingModel>
50
50
private readonly bool _useOsmColors ;
51
51
private readonly Vector4 _defaultColor = new Vector4 ( .9f , .9f , .9f , 1f ) ; // Color.FromArgb(230, 230, 230);
52
52
53
- public BuildingValidator ( ILogger logger , bool useOsmColors , string defaultHtmlColor = null )
53
+ public BuildingValidator ( ILogger logger , bool useOsmColors , string defaultHtmlColor = null ) : base ( logger )
54
54
{
55
55
this . _logger = logger ;
56
56
this . _useOsmColors = useOsmColors ;
@@ -61,22 +61,62 @@ public BuildingValidator(ILogger logger, bool useOsmColors, string defaultHtmlCo
61
61
62
62
}
63
63
64
- public override void ParseTags ( BuildingModel model )
64
+ public override bool ParseTags ( BuildingModel model )
65
65
{
66
- ParseTag < int > ( model , v => model . Levels = v , "building:levels" , "buildings:levels" ) ;
67
- ParseTag < string > ( model , v => model . IsPart = v . ToLower ( ) == "yes" , "building:part" , "buildings:part" ) ;
68
- ParseLengthTag ( model , v => model . MinHeight = v , "min_height" ) ;
69
- ParseLengthTag ( model , v => model . Height = v , "height" , "building:height" , "buildings:height" ) ;
66
+ ParseTag < string > ( model , "building" , v => model . Type = v ) ;
67
+ ParseTag < int > ( model , "building:levels" , v => model . Levels = v ) ;
68
+ ParseTag < int > ( model , "buildings:levels" , v => model . Levels = v ) ;
69
+ ParseTag < string > ( model , "buildings:part" , v => model . IsPart = v . ToLower ( ) == "yes" ) ;
70
+ ParseTag < string > ( model , "building:part" , v => model . IsPart = v . ToLower ( ) == "yes" ) ;
71
+ ParseLengthTag ( model , "min_height" , v => model . MinHeight = v ) ;
72
+ ParseLengthTag ( model , "height" , v => model . Height = v ) ;
70
73
if ( _useOsmColors )
71
74
{
72
- ParseTag < string , Vector4 > ( model , htmlColor => HtmlColorToVec4 ( htmlColor ) , v => model . Color = v , "building:colour" , "building:color" ) ;
73
- ParseTag < string , Vector4 > ( model , htmlColor => HtmlColorToVec4 ( htmlColor ) , v => model . RoofColor = v , "roof:colour" , "roof:color" ) ;
75
+ ParseTag < string , Vector4 > ( model , "building:colour" , htmlColor => HtmlColorToVec4 ( htmlColor ) , v => model . Color = v ) ;
76
+ ParseTag < string , Vector4 > ( model , "roof:colour" , htmlColor => HtmlColorToVec4 ( htmlColor ) , v => model . RoofColor = v ) ;
74
77
}
75
78
else
76
79
{
77
80
model . Color = _defaultColor ;
78
81
// no roof color, it would duplicate roof vertices
79
82
}
83
+
84
+ ParseLengthTag ( model , "building:height" , v =>
85
+ {
86
+ if ( model . Height != null )
87
+ {
88
+ _logger . LogWarning ( $ "Height is passed as height and building:height, got value { v } ") ;
89
+ }
90
+ model . Height = v ;
91
+ } ) ;
92
+
93
+ return true ;
94
+ }
95
+
96
+
97
+ public override BuildingModel CreateModel ( Feature feature )
98
+ {
99
+ if ( feature == null ) return null ;
100
+
101
+ BuildingModel model = null ;
102
+ switch ( feature . Geometry . Type )
103
+ {
104
+ case GeoJSON . Net . GeoJSONObjectType . Polygon :
105
+ model = ConvertBuildingGeometry ( ( Polygon ) feature . Geometry , ref base . _totalPoints ) ;
106
+ break ;
107
+ default :
108
+ _logger . LogDebug ( $ "{ feature . Geometry . Type } not supported for { nameof ( BuildingModel ) } { feature . Id } .") ;
109
+ break ;
110
+ }
111
+
112
+ if ( model != null )
113
+ {
114
+ model . Id = feature . Id ;
115
+ model . Tags = feature . Properties ;
116
+ }
117
+
118
+
119
+ return model ;
80
120
}
81
121
82
122
private Vector4 HtmlColorToVec4 ( string htmlColor )
@@ -95,115 +135,65 @@ private Vector4 HtmlColorToVec4(string htmlColor)
95
135
return new Vector4 ( componentRemap ( color . R ) , componentRemap ( color . G ) , componentRemap ( color . B ) , componentRemap ( color . A ) ) ;
96
136
}
97
137
98
- private void ParseTag < T > ( BuildingModel model , Action < T > updateAction , params string [ ] tagNames )
99
- {
100
- ParseTag < T , T > ( model , t => t , updateAction , tagNames ) ;
101
- }
102
- private void ParseTag < Tin , Tout > ( BuildingModel model , Func < Tin , Tout > transformFunc , Action < Tout > updateAction , params string [ ] tagNames )
103
- {
104
- foreach ( var tagName in tagNames )
105
- {
106
- if ( model . Tags . TryGetValue ( tagName , out object val ) )
107
- {
108
- try
109
- {
110
- Tin typedVal = ( Tin ) Convert . ChangeType ( val , typeof ( Tin ) , CultureInfo . InvariantCulture ) ;
111
- Tout outVal = transformFunc ( typedVal ) ;
112
- updateAction ( outVal ) ;
113
138
114
- break ;
115
- }
116
- catch ( Exception ex )
117
- {
118
- _logger . LogWarning ( $ "Cannot convert tag value { tagName } , got value { val } . { ex . Message } ") ;
119
- }
120
- }
121
- }
122
- }
139
+
123
140
// Parse with unit conversion to meters
124
- private void ParseLengthTag ( BuildingModel model , Action < double > updateAction , params string [ ] tagNames )
141
+ private void ParseLengthTag ( BuildingModel model , string tagName , Action < double > updateAction )
125
142
{
126
- foreach ( var tagName in tagNames )
127
- if ( model . Tags . TryGetValue ( tagName , out object val ) )
143
+ if ( model . Tags . TryGetValue ( tagName , out object val ) )
144
+ {
145
+ try
128
146
{
129
- try
147
+ // Will capture 4 items : inputval / sign / value / unit
148
+ var match = Regex . Match ( val . ToString ( ) , ValueAndUnitRegex , RegexOptions . Singleline | RegexOptions . Compiled ) ;
149
+ if ( match . Success )
130
150
{
131
- // Will capture 4 items : inputval / sign / value / unit
132
- var match = Regex . Match ( val . ToString ( ) , ValueAndUnitRegex , RegexOptions . Singleline | RegexOptions . Compiled ) ;
133
- if ( match . Success )
134
- {
135
- var groups = match . Groups [ 0 ] ;
136
- int sign = match . Groups [ 1 ] . Value == "-" ? - 1 : 1 ;
137
- string valueStr = match . Groups [ 2 ] . Value ;
138
- double typedVal = sign * double . Parse ( valueStr , CultureInfo . InvariantCulture ) ;
139
-
140
- string unit = match . Groups [ 3 ] . Value ;
141
- double factor = 1d ;
142
- switch ( unit . ToLower ( ) )
143
- {
144
- case "ft" :
145
- case "feet" :
146
- case "foot" :
147
- case "'" :
148
- factor = 0.3048009193 ;
149
- break ;
150
-
151
- case "" :
152
- factor = 1d ;
153
- break ;
154
- case "m" :
155
- case "meters" :
156
- factor = 1d ;
157
- break ;
158
- default :
159
- throw new NotSupportedException ( $ "Length unit { unit } conversion is not supported.") ;
160
- }
161
-
162
- typedVal *= factor ;
163
-
164
- updateAction ( typedVal ) ;
165
-
166
- break ;
167
- }
168
- else
151
+ var groups = match . Groups [ 0 ] ;
152
+ int sign = match . Groups [ 1 ] . Value == "-" ? - 1 : 1 ;
153
+ string valueStr = match . Groups [ 2 ] . Value ;
154
+ double typedVal = sign * double . Parse ( valueStr , CultureInfo . InvariantCulture ) ;
155
+
156
+ string unit = match . Groups [ 3 ] . Value ;
157
+ double factor = 1d ;
158
+ switch ( unit . ToLower ( ) )
169
159
{
170
- _logger . LogWarning ( $ "Cannot extract value and unit for tag { tagName } , got value { val } .") ;
160
+ case "ft" :
161
+ case "feet" :
162
+ case "foot" :
163
+ case "'" :
164
+ factor = 0.3048009193 ;
165
+ break ;
166
+
167
+ case "" :
168
+ factor = 1d ;
169
+ break ;
170
+ case "m" :
171
+ case "meters" :
172
+ factor = 1d ;
173
+ break ;
174
+ default :
175
+ throw new NotSupportedException ( $ "Length unit { unit } conversion is not supported.") ;
171
176
}
172
177
178
+ typedVal *= factor ;
173
179
180
+ updateAction ( typedVal ) ;
174
181
}
175
- catch ( Exception ex )
182
+ else
176
183
{
177
- _logger . LogWarning ( $ "Cannot convert tag value { tagName } , got value { val } . { ex . Message } ") ;
184
+ _logger . LogWarning ( $ "Cannot extract value and unit for tag { tagName } , got value { val } .") ;
178
185
}
179
- }
180
- }
181
186
182
- public override BuildingModel CreateModel ( Feature feature )
183
- {
184
- if ( feature == null ) return null ;
185
187
186
- BuildingModel model = null ;
187
- switch ( feature . Geometry . Type )
188
- {
189
- case GeoJSON . Net . GeoJSONObjectType . Polygon :
190
- model = ConvertBuildingGeometry ( ( Polygon ) feature . Geometry , ref base . _totalPoints ) ;
191
- break ;
192
- default :
193
- _logger . LogDebug ( $ "{ feature . Geometry . Type } not supported for { nameof ( BuildingModel ) } { feature . Id } .") ;
194
- break ;
195
- }
196
-
197
- if ( model != null )
198
- {
199
- model . Id = feature . Id ;
200
- model . Tags = feature . Properties ;
188
+ }
189
+ catch ( Exception ex )
190
+ {
191
+ _logger . LogWarning ( $ "Cannot convert tag value { tagName } , got value { val } . { ex . Message } ") ;
192
+ }
201
193
}
202
-
203
-
204
- return model ;
205
194
}
206
195
196
+
207
197
private BuildingModel ConvertBuildingGeometry ( Polygon poly , ref int geoPointIdCounter )
208
198
{
209
199
// Can't do it with a linq + lambda because of ref int param
0 commit comments