Skip to content

Commit

Permalink
Memory optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
chubrik committed May 9, 2019
1 parent 446d9d2 commit 0501917
Show file tree
Hide file tree
Showing 14 changed files with 270 additions and 198 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: csharp
mono: none
dotnet: 2.1
dotnet: 2.2
script:
- dotnet restore OsmDataKit.sln
24 changes: 0 additions & 24 deletions OsmDataKit/Data/DataConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,6 @@ public static NodeObject ToObject(NodeData data)
Debug.Assert(data != null);
Debug.Assert(data?.Coords?.Length == 2);

if (data == null)
throw new ArgumentNullException(nameof(data));

if (data.Coords?.Length != 2)
throw new ArgumentException(nameof(data));

return new NodeObject(
id: data.Id,
latitude: data.Coords[0],
Expand All @@ -151,12 +145,6 @@ public static WayObject ToObject(WayData data, IDictionary<long, NodeObject> all
Debug.Assert(data != null);
Debug.Assert(allNodes != null);

if (data == null)
throw new ArgumentNullException(nameof(data));

if (allNodes == null)
throw new ArgumentNullException(nameof(allNodes));

return new WayObject(
id: data.Id,
nodes: data.NodeIds.Where(allNodes.ContainsKey).Select(i => allNodes[i]).ToList(),
Expand All @@ -167,9 +155,6 @@ public static RelationObject ToObject(RelationData data)
{
Debug.Assert(data != null);

if (data == null)
throw new ArgumentNullException(nameof(data));

return new RelationObject(
id: data.Id,
tags: data.Tags);
Expand All @@ -181,15 +166,6 @@ public static RelationMemberObject ToObject(RelationMemberData data, GeoObject g
Debug.Assert(geo != null);
Debug.Assert(geo?.Type == data.Type);

if (data == null)
throw new ArgumentNullException(nameof(data));

if (geo == null)
throw new ArgumentNullException(nameof(geo));

if (geo.Type != data.Type)
throw new ArgumentException(nameof(geo));

return new RelationMemberObject(
role: data.Role,
geo: geo);
Expand Down
14 changes: 8 additions & 6 deletions OsmDataKit/Extensions/GeoCoordsCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ namespace OsmDataKit
{
public static class GeoCoordsCollectionExtensions
{
public static GeoCoords AverageCoords(this IReadOnlyCollection<IGeoCoords> coordsColletion)
public static GeoCoords AverageCoords(this IEnumerable<IGeoCoords> coordsColletion)
{
var minLat = coordsColletion.Min(i => i.Latitude);
var maxLat = coordsColletion.Max(i => i.Latitude);
var minLong = coordsColletion.Min(i => i.Longitude);
var maxLong = coordsColletion.Max(i => i.Longitude);
return new GeoCoords((minLat + maxLat) / 2, (minLong + maxLong) / 2);
//todo AverageCoords
var coordsList = coordsColletion.ToList();
var minLat2 = coordsList.Min(i => i.Latitude);
var maxLat2 = coordsList.Max(i => i.Latitude);
var minLong = coordsList.Min(i => i.Longitude);
var maxLong = coordsList.Max(i => i.Longitude);
return new GeoCoords((minLat2 + maxLat2) / 2, (minLong + maxLong) / 2);
}
}
}
25 changes: 25 additions & 0 deletions OsmDataKit/Extensions/GeoObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;

namespace OsmDataKit
{
public static class GeoObjectExtensions
{
public static IGeoCoords GetCenterCoords(this GeoObject geo)
{
switch (geo)
{
case NodeObject node:
return node;

case WayObject way:
return way.Nodes.AverageCoords();

case RelationObject relation:
return relation.GetAllNestedNodes().AverageCoords();

default:
throw new ArgumentOutOfRangeException(nameof(geo));
}
}
}
}
17 changes: 17 additions & 0 deletions OsmDataKit/Extensions/RelationMemberObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;
using System.Linq;

namespace OsmDataKit
{
public static class RelationMemberObjectExtensions
{
public static IEnumerable<NodeObject> GetNodes(this IEnumerable<RelationMemberObject> members) =>
members.Where(i => i.Geo is NodeObject).Select(i => i.Geo as NodeObject);

public static IEnumerable<WayObject> GetWays(this IEnumerable<RelationMemberObject> members) =>
members.Where(i => i.Geo is WayObject).Select(i => i.Geo as WayObject);

public static IEnumerable<RelationObject> GetRelations(this IEnumerable<RelationMemberObject> members) =>
members.Where(i => i.Geo is RelationObject).Select(i => i.Geo as RelationObject);
}
}
54 changes: 41 additions & 13 deletions OsmDataKit/Extensions/RelationObjectExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,53 @@
using OsmSharp;
using System;
using System.Collections.Generic;
using System.Linq;

namespace OsmDataKit
{
public static class RelationObjectExtensions
{
public static IEnumerable<NodeObject> Nodes(this RelationObject relation) =>
relation.Members.Where(i => i.Geo.Type == OsmGeoType.Node)
.Select(i => (NodeObject)i.Geo);
public static IEnumerable<NodeObject> GetNodes(this RelationObject relation) =>
relation.Members.GetNodes();

public static IEnumerable<WayObject> Ways(this RelationObject relation) =>
relation.Members.Where(i => i.Geo.Type == OsmGeoType.Way)
.Select(i => (WayObject)i.Geo);
public static IEnumerable<WayObject> GetWays(this RelationObject relation) =>
relation.Members.GetWays();

public static IEnumerable<RelationObject> Relations(this RelationObject relation) =>
relation.Members.Where(i => i.Geo.Type == OsmGeoType.Relation)
.Select(i => (RelationObject)i.Geo);
public static IEnumerable<RelationObject> GetRelations(this RelationObject relation) =>
relation.Members.GetRelations();

public static IEnumerable<NodeObject> GetAllNodes(this RelationObject relation) =>
relation.Nodes().Concat(relation.Ways().SelectMany(i => i.Nodes))
.Concat(relation.Relations().SelectMany(i => i.GetAllNodes()));
public static IEnumerable<NodeObject> GetAllNestedNodes(this RelationObject relation) =>
relation.GetNodes().Concat(relation.GetWays().SelectMany(i => i.Nodes))
.Concat(relation.GetRelations().SelectMany(i => i.GetAllNestedNodes()));

internal static bool GetIsBroken(this RelationObject relation)
{
foreach (var member in relation.Members)
{
switch (member.Geo)
{
case NodeObject node:
break;

case WayObject way:

if (way.IsBroken)
return true;

break;

case RelationObject rel:

if (rel.GetIsBroken())
return true;

break;

default:
throw new ArgumentOutOfRangeException(nameof(member));
}
}

return false;
}
}
}
12 changes: 12 additions & 0 deletions OsmDataKit/Models/GeoCoords.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using System;
using System.Diagnostics;

namespace OsmDataKit
{
public class GeoCoords : IGeoCoords
Expand All @@ -7,6 +10,15 @@ public class GeoCoords : IGeoCoords

public GeoCoords(double latitude, double longitude)
{
Debug.Assert(latitude >= -90 && latitude <= 90);
Debug.Assert(longitude >= -180 && longitude <= 180);

if (latitude < -90 || latitude > 90)
throw new ArgumentOutOfRangeException(nameof(latitude));

if (longitude < -180 || longitude > 180)
throw new ArgumentOutOfRangeException(nameof(longitude));

Latitude = latitude;
Longitude = longitude;
}
Expand Down
48 changes: 26 additions & 22 deletions OsmDataKit/Models/GeoObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,29 @@ namespace OsmDataKit
public abstract class GeoObject
{
public long Id { get; }
public abstract OsmGeoType Type { get; }

//todo tags & data
public IReadOnlyDictionary<string, string> Tags { get; }
public Dictionary<string, string> Data { get; }
private IReadOnlyDictionary<string, string> _tags;
public IReadOnlyDictionary<string, string> Tags => _tags ?? (_tags = new Dictionary<string, string>(0));

public abstract OsmGeoType Type { get; }
public abstract bool IsBroken { get; }
public abstract IGeoCoords AverageCoords { get; }
public string Url => $"https://www.openstreetmap.org/{Type.ToString().ToLower()}/{Id}";
private Dictionary<string, string> _data;
public Dictionary<string, string> Data => _data ?? (_data = new Dictionary<string, string>(0));

protected GeoObject(
long id,
IReadOnlyDictionary<string, string> tags,
Dictionary<string, string> data)
{
Debug.Assert(id > 0);

Id = id;

if (tags?.Count > 0)
_tags = tags;

if (data?.Count > 0)
_data = data;
}

#region Title

Expand All @@ -37,12 +51,10 @@ public string Title

_titleAssigned = true;

if (Tags.Count == 0)
return null;

foreach (var tagName in _tagNames)
if (Tags.TryGetValue(tagName, out var title) && !title.IsNullOrWhiteSpace())
return _title = title.Trim();
if (_tags != null)
foreach (var tagName in _tagNames)
if (Tags.TryGetValue(tagName, out var title) && !title.IsNullOrWhiteSpace())
return _title = title.Trim();

return null;
}
Expand All @@ -57,15 +69,7 @@ public string Title

#endregion

protected GeoObject(
long id,
IReadOnlyDictionary<string, string> tags,
Dictionary<string, string> data)
{
Id = id;
Tags = tags;
Data = data;
}
public string SourceUrl => $"https://www.openstreetmap.org/{Type.ToString().ToLower()}/{Id}";

#if DEBUG
private string DebugInfo =>
Expand Down
13 changes: 2 additions & 11 deletions OsmDataKit/Models/NodeObject.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
using OsmSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace OsmDataKit
{
public class NodeObject : GeoObject, IGeoCoords
{
public override OsmGeoType Type => OsmGeoType.Node;

public double Latitude { get; }
public double Longitude { get; }

public override OsmGeoType Type => OsmGeoType.Node;
public override bool IsBroken => false;
public override IGeoCoords AverageCoords => this;

public NodeObject(
long id, double latitude, double longitude,
IReadOnlyDictionary<string, string> tags = null,
Expand All @@ -23,12 +20,6 @@ public NodeObject(
Debug.Assert(latitude >= -90 && latitude <= 90);
Debug.Assert(longitude >= -180 && longitude <= 180);

if (latitude < -90 || latitude > 90)
throw new ArgumentOutOfRangeException(nameof(latitude));

if (longitude < -180 || longitude > 180)
throw new ArgumentOutOfRangeException(nameof(longitude));

Latitude = latitude;
Longitude = longitude;
}
Expand Down
9 changes: 4 additions & 5 deletions OsmDataKit/Models/RelationMemberObject.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Kit;
using OsmSharp;
using System;
using System.Diagnostics;

Expand All @@ -12,14 +12,13 @@ public class RelationMemberObject
public string Role { get; }
public GeoObject Geo { get; }

public OsmGeoType Type => Geo.Type;

public RelationMemberObject(string role, GeoObject geo)
{
Debug.Assert(!role.IsNullOrEmpty());
Debug.Assert(role != null);
Debug.Assert(geo != null);

if (role.IsNullOrEmpty())
throw new ArgumentException(nameof(role));

Role = role;
Geo = geo ?? throw new ArgumentNullException(nameof(geo));
}
Expand Down
32 changes: 12 additions & 20 deletions OsmDataKit/Models/RelationObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace OsmDataKit
{
public class RelationObject : GeoObject
{
public IReadOnlyList<RelationMemberObject> Members { get; internal set; }

public override OsmGeoType Type => OsmGeoType.Relation;

private bool? _isBroken;

public override bool IsBroken =>
_isBroken ?? (_isBroken = Members.Any(i => i.Geo.IsBroken)).Value;

private GeoCoords _averageCoords;

public override IGeoCoords AverageCoords =>
_averageCoords ?? (_averageCoords = this.GetAllNodes().ToList().AverageCoords());

public void SetMembers(IReadOnlyList<RelationMemberObject> members)
{
Debug.Assert(members != null);
Members = members ?? throw new ArgumentNullException(nameof(members));
_isBroken = null;
_averageCoords = null;
}
public IReadOnlyList<RelationMemberObject> Members { get; internal set; }

//todo internat ctor
internal RelationObject(
Expand All @@ -45,5 +26,16 @@ public RelationObject(
{
SetMembers(members);
}

private bool? _isBroken;
public bool IsBroken => _isBroken ?? (_isBroken = this.GetIsBroken()).Value;

public void SetMembers(IReadOnlyList<RelationMemberObject> members)
{
Debug.Assert(members?.Count > 0);

Members = members ?? throw new ArgumentNullException(nameof(members));
_isBroken = null;
}
}
}
Loading

0 comments on commit 0501917

Please sign in to comment.