Skip to content

Commit 3e158c4

Browse files
committed
Merge branch 'develop'
2 parents 164eaf9 + 71e29c6 commit 3e158c4

34 files changed

+1632
-904
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,3 +352,4 @@ MigrationBackup/
352352
Samples/secrets.json
353353
.DS_Store
354354
*.DS_Store
355+
DEM.Net.Extension.Tests/secrets.json

DEM.Net.Extension.Osm/Implementation/Buildings/BuildingModel.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ namespace DEM.Net.Extension.Osm.Buildings
88
{
99
public class BuildingModel : CommonModel
1010
{
11-
public List<BuildingModel> Parts { get; set; }
12-
public List<GeoPoint> ExteriorRing { get; set; }
11+
public List<GeoPoint> ExteriorRing { get; set; }
1312

1413
public List<List<GeoPoint>> InteriorRings { get; set; }
1514

@@ -20,16 +19,12 @@ public IEnumerable<GeoPoint> Points
2019
return ExteriorRing.Concat(this.InteriorRings == null ? Enumerable.Empty<GeoPoint>() : this.InteriorRings.SelectMany(r => r));
2120
}
2221
}
23-
24-
25-
2622
public BuildingModel(List<GeoPoint> exteriorRingPoints, List<List<GeoPoint>> interiorRings)
2723
{
2824
this.ExteriorRing = exteriorRingPoints;
2925
this.InteriorRings = interiorRings ?? new List<List<GeoPoint>>();
3026
}
3127

32-
3328
// building:levels
3429
// height
3530
// min_height
@@ -38,10 +33,21 @@ public BuildingModel(List<GeoPoint> exteriorRingPoints, List<List<GeoPoint>> int
3833
public double? Height { get; set; }
3934

4035
public double? ComputedFloorAltitude { get; set; }
41-
public double ComputedRoofAltitude { get; set; }
36+
public double? ComputedRoofAltitude { get; set; }
4237
public bool HasHeightInformation { get; set; }
4338
public bool IsPart { get; set; }
4439
public Vector4? Color { get; set; }
4540
public Vector4? RoofColor { get; set; }
41+
public BuildingModel Parent { get; internal set; }
42+
43+
public override string ToString()
44+
{
45+
string outStr = string.Concat(IsPart ? "part" : "", " "
46+
, Id, " "
47+
, "Height: ", Height, " "
48+
, "Levels: ", Levels, " "
49+
, "MinHeight: ", MinHeight, " ");
50+
return outStr;
51+
}
4652
}
4753
}

DEM.Net.Extension.Osm/Implementation/Buildings/BuildingValidator.cs

Lines changed: 90 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class BuildingValidator : OsmModelFactory<BuildingModel>
5050
private readonly bool _useOsmColors;
5151
private readonly Vector4 _defaultColor = new Vector4(.9f, .9f, .9f, 1f); // Color.FromArgb(230, 230, 230);
5252

53-
public BuildingValidator(ILogger logger, bool useOsmColors, string defaultHtmlColor = null)
53+
public BuildingValidator(ILogger logger, bool useOsmColors, string defaultHtmlColor = null) : base(logger)
5454
{
5555
this._logger = logger;
5656
this._useOsmColors = useOsmColors;
@@ -61,22 +61,62 @@ public BuildingValidator(ILogger logger, bool useOsmColors, string defaultHtmlCo
6161

6262
}
6363

64-
public override void ParseTags(BuildingModel model)
64+
public override bool ParseTags(BuildingModel model)
6565
{
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);
7073
if (_useOsmColors)
7174
{
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);
7477
}
7578
else
7679
{
7780
model.Color = _defaultColor;
7881
// no roof color, it would duplicate roof vertices
7982
}
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;
80120
}
81121

82122
private Vector4 HtmlColorToVec4(string htmlColor)
@@ -95,115 +135,65 @@ private Vector4 HtmlColorToVec4(string htmlColor)
95135
return new Vector4(componentRemap(color.R), componentRemap(color.G), componentRemap(color.B), componentRemap(color.A));
96136
}
97137

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);
113138

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+
123140
// 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)
125142
{
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
128146
{
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)
130150
{
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())
169159
{
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.");
171176
}
172177

178+
typedVal *= factor;
173179

180+
updateAction(typedVal);
174181
}
175-
catch (Exception ex)
182+
else
176183
{
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}.");
178185
}
179-
}
180-
}
181186

182-
public override BuildingModel CreateModel(Feature feature)
183-
{
184-
if (feature == null) return null;
185187

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+
}
201193
}
202-
203-
204-
return model;
205194
}
206195

196+
207197
private BuildingModel ConvertBuildingGeometry(Polygon poly, ref int geoPointIdCounter)
208198
{
209199
// Can't do it with a linq + lambda because of ref int param

0 commit comments

Comments
 (0)