Skip to content

Commit

Permalink
Merge branch 'hotfix/v0.13.1' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
philipbelesky committed Oct 26, 2021
2 parents b8d1b77 + 4f16279 commit e107368
Show file tree
Hide file tree
Showing 17 changed files with 100 additions and 66 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.13.1] - 2021-10-26
### Fixed
- Issue where some buildings would be extruded upside down.
- Issue where parsing the XML file would fail in cultures that employ commas as the radix (decimal separator) character.

## [0.13.0] - 2021-10-19
### Added
- New *Filter Tags* component that allows users to take the output of any *Extract* component and select Nodes/Ways/Buildings matching specific tags (using the same GUI) within just the tags present in that collection.
Expand Down
34 changes: 34 additions & 0 deletions Caribou.Tests/Models/TestSingleBoundsParsing.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace Caribou.Tests.Models
{
using System.Globalization;
using System.Threading;
using Caribou.Models;
using Caribou.Tests.Cases;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand All @@ -19,6 +21,38 @@ public void ParseBoundsViaXMLReader()
CheckResult();
}

[TestMethod]
public void ParseBoundsViaXMLReaderLocaleA()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", false);
Caribou.Processing.ParseViaXMLReader.GetBounds(ref results, true);
CheckResult();
}

[TestMethod]
public void ParseBoundsViaXMLReaderLocaleB()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR", false);
Caribou.Processing.ParseViaXMLReader.GetBounds(ref results, true);
CheckResult();
}

[TestMethod]
public void ParseBoundsViaXMLReaderLocaleC()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("it-IT", false);
Caribou.Processing.ParseViaXMLReader.GetBounds(ref results, true);
CheckResult();
}

[TestMethod]
public void ParseBoundsViaXMLReaderLocaleD()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("zh-Hans", false);
Caribou.Processing.ParseViaXMLReader.GetBounds(ref results, true);
CheckResult();
}

[TestMethod]
public void ParseBoundsViaXMLDocument()
{
Expand Down
4 changes: 2 additions & 2 deletions Caribou/Caribou.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
<PackageLicenseFile>LICENSE.md</PackageLicenseFile>
<PackageProjectUrl>https://philipbelesky.com</PackageProjectUrl>
<RepositoryUrl>https://github.com/philipbelesky/Caribou</RepositoryUrl>
<AssemblyVersion>0.13.0.0</AssemblyVersion>
<FileVersion>0.13.0.0</FileVersion>
<AssemblyVersion>0.13.1.0</AssemblyVersion>
<FileVersion>0.13.1.0</FileVersion>
<Version>0.13.0-beta</Version>
</PropertyGroup>

Expand Down
16 changes: 8 additions & 8 deletions Caribou/Processing/ParseViaLinq.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ public static void FindItemsByTag(ref RequestHandler request)
// }

// var tagValue = result.Attributes("v").First().Value;
// var lat = Convert.ToDouble(result.Parent.Attributes("lat").First().Value);
// var lon = Convert.ToDouble(result.Parent.Attributes("lon").First().Value);
// var lat = Convert.ToDouble(result.Parent.Attributes("lat").First().Value, System.Globalization.CultureInfo.InvariantCulture);
// var lon = Convert.ToDouble(result.Parent.Attributes("lon").First().Value, System.Globalization.CultureInfo.InvariantCulture);
// matches.AddNodeGivenFeature(tagKey, tagValue, new Coord(lat, lon));
// }
// }
Expand All @@ -56,8 +56,8 @@ public static void FindItemsByTag(ref RequestHandler request)
// continue;
// }

// var lat = Convert.ToDouble(result.Attributes("lat").First().Value);
// var lon = Convert.ToDouble(result.Attributes("lon").First().Value);
// var lat = Convert.ToDouble(result.Attributes("lat").First().Value, System.Globalization.CultureInfo.InvariantCulture);
// var lon = Convert.ToDouble(result.Attributes("lon").First().Value, System.Globalization.CultureInfo.InvariantCulture);
// matches.AddNodeGivenFeatureAndSubFeature(tagKey, tagValue, new Coord(lat, lon));
// }
// }
Expand All @@ -80,10 +80,10 @@ public static void GetBounds(ref RequestHandler result)
{
var xml = XDocument.Parse(providedXML);
var boundsElement = (from el in xml.Descendants("bounds") select el).First();
var minLat = Convert.ToDouble(boundsElement.Attributes("minlat").First().Value);
var minLon = Convert.ToDouble(boundsElement.Attributes("minlon").First().Value);
var maxLat = Convert.ToDouble(boundsElement.Attributes("maxlat").First().Value);
var maxLon = Convert.ToDouble(boundsElement.Attributes("maxlon").First().Value);
var minLat = Convert.ToDouble(boundsElement.Attributes("minlat").First().Value, System.Globalization.CultureInfo.InvariantCulture);
var minLon = Convert.ToDouble(boundsElement.Attributes("minlon").First().Value, System.Globalization.CultureInfo.InvariantCulture);
var maxLat = Convert.ToDouble(boundsElement.Attributes("maxlat").First().Value, System.Globalization.CultureInfo.InvariantCulture);
var maxLon = Convert.ToDouble(boundsElement.Attributes("maxlon").First().Value, System.Globalization.CultureInfo.InvariantCulture);
var bounds = new Tuple<Coord, Coord>(new Coord(minLat, minLon), new Coord(maxLat, maxLon));
result.AllBounds.Add(bounds);
CheckBounds(bounds, ref currentMinLat, ref currentMinLon, ref currentMaxLat, ref currentMaxLon);
Expand Down
16 changes: 8 additions & 8 deletions Caribou/Processing/ParseViaXMLDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ public static void FindItemsByTag(ref RequestHandler request)
// foreach (XmlNode featureTag in nodeList)
// {
// var tagValue = featureTag.Attributes.GetNamedItem("v").Value;
// lat = Convert.ToDouble(featureTag.ParentNode.Attributes.GetNamedItem("lat").Value);
// lon = Convert.ToDouble(featureTag.ParentNode.Attributes.GetNamedItem("lon").Value);
// lat = Convert.ToDouble(featureTag.ParentNode.Attributes.GetNamedItem("lat").Value, System.Globalization.CultureInfo.InvariantCulture);
// lon = Convert.ToDouble(featureTag.ParentNode.Attributes.GetNamedItem("lon").Value, System.Globalization.CultureInfo.InvariantCulture);
// matches.AddNodeGivenFeature(tagKey, tagValue, new Coord(lat, lon));
// }
// }
Expand All @@ -45,8 +45,8 @@ public static void FindItemsByTag(ref RequestHandler request)
// nodeList = root.SelectNodes("/osm/node/tag[@k='" + tagKey + "' and @v='" + tagValue + "']");
// foreach (XmlNode featureTag in nodeList)
// {
// lat = Convert.ToDouble(featureTag.ParentNode.Attributes.GetNamedItem("lat").Value);
// lon = Convert.ToDouble(featureTag.ParentNode.Attributes.GetNamedItem("lon").Value);
// lat = Convert.ToDouble(featureTag.ParentNode.Attributes.GetNamedItem("lat").Value, System.Globalization.CultureInfo.InvariantCulture);
// lon = Convert.ToDouble(featureTag.ParentNode.Attributes.GetNamedItem("lon").Value, System.Globalization.CultureInfo.InvariantCulture);
// matches.AddNodeGivenFeatureAndSubFeature(tagKey, tagValue, new Coord(lat, lon));
// }
// }
Expand Down Expand Up @@ -80,25 +80,25 @@ public static void GetBounds(ref RequestHandler result)
private static void CheckBounds(XmlNode node, ref double? currentMinLat, ref double? currentMinLon,
ref double? currentMaxLat, ref double? currentMaxLon)
{
var boundsMinLat = Convert.ToDouble(node.Attributes.GetNamedItem("minlat").Value);
var boundsMinLat = Convert.ToDouble(node.Attributes.GetNamedItem("minlat").Value, System.Globalization.CultureInfo.InvariantCulture);
if (!currentMinLat.HasValue || boundsMinLat < currentMinLat)
{
currentMinLat = boundsMinLat;
}

var boundsMinLon = Convert.ToDouble(node.Attributes.GetNamedItem("minlon").Value);
var boundsMinLon = Convert.ToDouble(node.Attributes.GetNamedItem("minlon").Value, System.Globalization.CultureInfo.InvariantCulture);
if (!currentMinLon.HasValue || boundsMinLon < currentMinLon)
{
currentMinLon = boundsMinLon;
}

var boundsMaxLat = Convert.ToDouble(node.Attributes.GetNamedItem("maxlat").Value);
var boundsMaxLat = Convert.ToDouble(node.Attributes.GetNamedItem("maxlat").Value, System.Globalization.CultureInfo.InvariantCulture);
if (!currentMaxLat.HasValue || boundsMaxLat > currentMaxLat)
{
currentMaxLat = boundsMaxLat;
}

var boundsMaxLon = Convert.ToDouble(node.Attributes.GetNamedItem("maxlon").Value);
var boundsMaxLon = Convert.ToDouble(node.Attributes.GetNamedItem("maxlon").Value, System.Globalization.CultureInfo.InvariantCulture);
if (!currentMaxLon.HasValue || boundsMaxLon > currentMaxLon)
{
currentMaxLon = boundsMaxLon;
Expand Down
24 changes: 11 additions & 13 deletions Caribou/Processing/ParseViaXMLReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static class ParseViaXMLReader
{
private delegate void DispatchDelegate(XmlReader reader, ref RequestHandler request,
int fileIndex, bool onlyBuildings = false);

private static readonly CultureInfo CI = CultureInfo.InvariantCulture;

public static void FindItemsByTag(ref RequestHandler request, OSMGeometryType typeToFind, bool pathIsContents = false)
{
Expand Down Expand Up @@ -50,7 +50,6 @@ public static void FindNodesInXML(XmlReader reader, ref RequestHandler request,
double currentLat = 0;
double currentLon = 0;
var currentNodeMetaData = new Dictionary<string, string>();
var ci = CultureInfo.InvariantCulture;
var xli = (IXmlLineInfo)reader; // Used to track read progress
var nodesCollected = 0;

Expand All @@ -63,12 +62,12 @@ public static void FindNodesInXML(XmlReader reader, ref RequestHandler request,
if (reader.Name == "node")
{
currentNodeId = reader.GetAttribute("id");
currentLat = Convert.ToDouble(reader.GetAttribute("lat"));
currentLon = Convert.ToDouble(reader.GetAttribute("lon"));
currentLat = Convert.ToDouble(reader.GetAttribute("lat"), CI);
currentLon = Convert.ToDouble(reader.GetAttribute("lon"), CI);
}
else if (reader.Name == "tag")
{
currentNodeMetaData[reader.GetAttribute("k").ToLower(ci)] = reader.GetAttribute("v");
currentNodeMetaData[reader.GetAttribute("k").ToLower(CI)] = reader.GetAttribute("v");
}
else if (reader.Name == "way")
{
Expand All @@ -93,7 +92,6 @@ public static void FindWaysInXML(XmlReader reader, ref RequestHandler request, i
var currentWayNodes = new List<Coord>();
var allNodes = new Dictionary<string, Coord>();
var inANode = false; // Only needed for ways
var ci = CultureInfo.InvariantCulture;
var xli = (IXmlLineInfo)reader; // Used to track read progress
var waysCollected = 0;

Expand All @@ -110,8 +108,8 @@ public static void FindWaysInXML(XmlReader reader, ref RequestHandler request, i
{
var nodeId = reader.GetAttribute("id");
allNodes[nodeId] = new Coord(
Convert.ToDouble(reader.GetAttribute("lat")),
Convert.ToDouble(reader.GetAttribute("lon")));
Convert.ToDouble(reader.GetAttribute("lat"), CI),
Convert.ToDouble(reader.GetAttribute("lon"), CI));
}
else if (inANode && reader.Name == "nd")
{
Expand All @@ -120,7 +118,7 @@ public static void FindWaysInXML(XmlReader reader, ref RequestHandler request, i
}
else if (inANode && reader.Name == "tag")
{
currentWayMetaData[reader.GetAttribute("k").ToLower(ci)] = reader.GetAttribute("v");
currentWayMetaData[reader.GetAttribute("k").ToLower(CI)] = reader.GetAttribute("v");
}
else if (reader.Name == "relation")
{
Expand Down Expand Up @@ -185,10 +183,10 @@ public static void GetBounds(ref RequestHandler result, bool readPathAsContents
{
if (reader.Name == "bounds")
{
var minLat = Convert.ToDouble(reader.GetAttribute("minlat"));
var minLon = Convert.ToDouble(reader.GetAttribute("minlon"));
var maxLat = Convert.ToDouble(reader.GetAttribute("maxlat"));
var maxLon = Convert.ToDouble(reader.GetAttribute("maxlon"));
var minLat = Convert.ToDouble(reader.GetAttribute("minlat"), CI);
var minLon = Convert.ToDouble(reader.GetAttribute("minlon"), CI);
var maxLat = Convert.ToDouble(reader.GetAttribute("maxlat"), CI);
var maxLon = Convert.ToDouble(reader.GetAttribute("maxlon"), CI);
var bounds = new Tuple<Coord, Coord>(new Coord(minLat, minLon), new Coord(maxLat, maxLon));
result.AllBounds.Add(bounds);

Expand Down
4 changes: 2 additions & 2 deletions Caribou/Processing/ProgressReporting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ public static List<int> GetLineLengthsForFiles(List<string> xmlFilePaths, OSMGeo
try
{
int linesForFile = File.ReadLines(filePath).Count();
if (typeToFind == OSMGeometryType.Node)
linesForFile = Convert.ToInt32(linesForFile * 0.55); // Only half of the amount of a file is nodes
if (typeToFind == OSMGeometryType.Node) // Assume approximately half of the amount of a file is nodes
linesForFile = Convert.ToInt32(linesForFile * 0.55, System.Globalization.CultureInfo.InvariantCulture);
count.Add(linesForFile);
}
catch { // Usually when file path is unreadable/reachable
Expand Down
32 changes: 15 additions & 17 deletions Caribou/Processing/TranslateToXYManually.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,40 +66,38 @@ public static Dictionary<OSMTag, List<Brep>> BuildingBrepsFromCoords(ref Request

for (int i = entry.Value.Count - 1; i >= 0; i--)
{
var linePoints = new List<Point3d>();

var outlinePoints = new List<Point3d>();
foreach (var coord in entry.Value[i].Coords)
{
var pt = GetPointFromLatLong(coord, lengthPerDegree, result.MinBounds);
linePoints.Add(pt);
}
outlinePoints.Add(GetPointFromLatLong(coord, lengthPerDegree, result.MinBounds));

var polyLine = new PolylineCurve(linePoints); // Creating a polylinecurve from scratch makes invalid geometry
var height = GetBuildingHeights.ParseHeight(entry.Value[i].Tags, unitScale);
var outline = new PolylineCurve(outlinePoints); // Creating a polylinecurve from scratch makes invalid geometry

var height = GetBuildingHeights.ParseHeight(entry.Value[i].Tags, unitScale);
if (outputHeighted && height > 0.0) // Output heighted buildings
{
if (polyLine.ClosedCurveOrientation() == CurveOrientation.Clockwise)
height *= -1; // If curve plane's Z != global Z; extrude in opposite direction
var toHeight = new Vector3d(0, 0, height);

var builtVolume = Extrusion.Create(polyLine, height, true);
geometryResult[entry.Key].Add(builtVolume.ToBrep());
var envelope = Surface.CreateExtrusion(outline, toHeight);
var floor = Brep.CreatePlanarBreps(outline, tolerance);
outline.Translate(toHeight);
var roof = Brep.CreatePlanarBreps(outline, tolerance);

var volume = Brep.JoinBreps(new Brep[] { floor[0], envelope.ToBrep(), roof[0] }, tolerance);
geometryResult[entry.Key].Add(volume[0]);
}
else if (!outputHeighted && height == 0.0) // Output unheighted buildings
{
var builtSurface = Brep.CreatePlanarBreps(polyLine, tolerance);
var builtSurface = Brep.CreatePlanarBreps(outline, tolerance);
if (builtSurface != null && builtSurface.Length > 0)
geometryResult[entry.Key].Add(builtSurface[0]);
}
else // Item wasn't matched, so should be removed from result so it's metadata is not output
{
else // Item wasn't matched, so should be removed from result so its metadata is not output
entry.Value.RemoveAt(i);
}
}

geometryResult[entry.Key].Reverse(); // We iterated in reverse order, so swap list back to right direction
}


return geometryResult;
}

Expand Down
2 changes: 1 addition & 1 deletion Caribou/bin/Release/net45/manifest.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Caribou
version: 0.13.0
version: 0.13.1
authors:
- Philip Belesky
keywords:
Expand Down
Loading

0 comments on commit e107368

Please sign in to comment.