Skip to content

Commit

Permalink
Migrate to docker #641 - changed all related code to migrate graphhop…
Browse files Browse the repository at this point in the history
…per to docker.
  • Loading branch information
HarelM committed Apr 20, 2020
1 parent 8c6bec1 commit d41a8c7
Show file tree
Hide file tree
Showing 16 changed files with 98 additions and 141 deletions.
43 changes: 17 additions & 26 deletions IsraelHiking.API/Controllers/RoutingController.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using IsraelHiking.API.Executors;
using IsraelHiking.Common;
using IsraelHiking.Common.Extensions;
using IsraelHiking.DataAccessInterfaces;
using Microsoft.AspNetCore.Mvc;
using NetTopologySuite.Features;
using NetTopologySuite.Geometries;
using ProjNet.CoordinateSystems.Transformations;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;

Expand Down Expand Up @@ -53,38 +53,25 @@ public RoutingController(IGraphHopperGateway graphHopperGateway,
[ProducesResponseType(typeof(FeatureCollection), 200)]
public async Task<IActionResult> GetRouting(string from, string to, string type)
{
LineString lineString;

var profile = ConvertProfile(type);
var pointFrom = await GetGeographicPosition(from);
var pointTo = await GetGeographicPosition(to);
if (ModelState.IsValid == false)
{
return BadRequest(ModelState);
}
if (profile == ProfileType.None)
{
lineString = GetDenseStraightLine(pointFrom, pointTo);
}
else
{
lineString = await _graphHopperGateway.GetRouting(new RoutingGatewayRequest
Feature feature = profile == ProfileType.None
? GetDenseStraightLine(pointFrom, pointTo)
: await _graphHopperGateway.GetRouting(new RoutingGatewayRequest
{
From = from,
To = to,
From = pointFrom,
To = pointTo,
Profile = profile,
});
if (!lineString.Coordinates.Any())
{
lineString = _geometryFactory.CreateLineString(new[] { pointFrom, pointTo }) as LineString;
}
}
ElevationSetterHelper.SetElevation(lineString, _elevationDataStorage);
var table = new AttributesTable
{
{"Name", "Routing from " + @from + " to " + to + " profile type: " + profile},
{"Creator", "IsraelHikingMap"}
};
var feature = new Feature(lineString, table);
ElevationSetterHelper.SetElevation(feature.Geometry, _elevationDataStorage);
feature.Attributes.AddOrUpdate("Name", $"Routing from {@from} to {to} profile type: {profile}");
feature.Attributes.AddOrUpdate("Creator", "IsraelHikingMap");
return Ok(new FeatureCollection{ feature });
}

Expand All @@ -100,6 +87,9 @@ private static ProfileType ConvertProfile(string type)
profile = ProfileType.Bike;
break;
case RoutingType.FOUR_WHEEL_DRIVE:
profile = ProfileType.Car4WheelDrive;
break;
case RoutingType.CAR:
profile = ProfileType.Car;
break;
case RoutingType.NONE:
Expand Down Expand Up @@ -131,21 +121,22 @@ private async Task<Coordinate> GetGeographicPosition(string position)
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns></returns>
private LineString GetDenseStraightLine(Coordinate from, Coordinate to)
private Feature GetDenseStraightLine(Coordinate from, Coordinate to)
{
var itmFrom = _wgs84ItmMathTransform.Transform(from.X, from.Y);
var itmTo = _wgs84ItmMathTransform.Transform(to.X, to.Y);
var samples = (int)Math.Min(new Point(itmFrom.x, itmFrom.y).Distance(new Point(itmTo.x, itmTo.y)) / 30, 30);
if (samples == 0)
{
return _geometryFactory.CreateLineString(new[] {from, to}) as LineString;
return new Feature(_geometryFactory.CreateLineString(new[] {from, to}), new AttributesTable());
}
var coordinates = Enumerable.Range(0, samples + 1).Select(s => new CoordinateZ(
(to.X - from.X) * s / samples + from.X,
(to.Y - from.Y) * s / samples + from.Y,
0)
);
return _geometryFactory.CreateLineString(coordinates.ToArray()) as LineString;
var lineString = _geometryFactory.CreateLineString(coordinates.ToArray());
return new Feature(lineString, new AttributesTable());
}
}
}
2 changes: 0 additions & 2 deletions IsraelHiking.API/Controllers/UpdateController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ public async Task<IActionResult> PostUpdateData(UpdateRequest request)
return BadRequest("This operation can't be done from a remote client, please run this from the server");
}
if (request == null ||
request.Routing == false &&
request.Highways == false &&
request.PointsOfInterest == false &&
request.UpdateOsmFile == false &&
Expand All @@ -74,7 +73,6 @@ public async Task<IActionResult> PostUpdateData(UpdateRequest request)
{
request = new UpdateRequest
{
Routing = true,
Highways = true,
PointsOfInterest = true,
UpdateOsmFile = true,
Expand Down
18 changes: 0 additions & 18 deletions IsraelHiking.API/Services/Osm/DatabasesUpdaterService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,6 @@ private bool IsRelevantPointOfInterest(OsmGeo osm, List<KeyValuePair<string, str
/// <inheritdoc />
public async Task Rebuild(UpdateRequest request)
{
var rebuildRoutingTask = Task.CompletedTask;
if (request.Routing)
{
rebuildRoutingTask = RebuildRouting();
}
if (request.Highways)
{
await RebuildHighways();
Expand All @@ -177,19 +172,6 @@ public async Task Rebuild(UpdateRequest request)
{
await RebuildSiteMap();
}
await rebuildRoutingTask;
}

private async Task RebuildRouting()
{
_logger.LogInformation("Starting rebuilding routing database.");
using (var stream = _latestFileFetcherExecutor.Get())
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
await _graphHopperGateway.Rebuild(memoryStream);
}
_logger.LogInformation("Finished rebuilding routing database.");
}

private async Task RebuildPointsOfInterest()
Expand Down
1 change: 1 addition & 0 deletions IsraelHiking.Common/RouteSegmentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public static class RoutingType
{
public const string HIKE = "Hike";
public const string BIKE = "Bike";
public const string CAR = "Car";
public const string FOUR_WHEEL_DRIVE = "4WD";
public const string NONE = "None";
}
Expand Down
11 changes: 7 additions & 4 deletions IsraelHiking.Common/RoutingGatewayRequest.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
namespace IsraelHiking.Common
using NetTopologySuite.Geometries;

namespace IsraelHiking.Common
{
public enum ProfileType
{
None,
Foot,
Bike,
Car,
Car4WheelDrive,
Car
}

public class RoutingGatewayRequest
{
public string From { get; set; }
public string To { get; set; }
public Coordinate From { get; set; }
public Coordinate To { get; set; }
public ProfileType Profile { get; set; }
}
}
4 changes: 0 additions & 4 deletions IsraelHiking.Common/UpdateRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ public class UpdateRequest
/// </summary>
public bool UpdateOsmFile { get; set; }
/// <summary>
/// Update site's routing database
/// </summary>
public bool Routing { get; set; }
/// <summary>
/// Update points of interest database
/// </summary>
public bool PointsOfInterest { get; set; }
Expand Down
44 changes: 20 additions & 24 deletions IsraelHiking.DataAccess/GraphHopperGateway.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using IsraelHiking.Common;
using IsraelHiking.DataAccessInterfaces;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NetTopologySuite.Features;
using NetTopologySuite.Geometries;
using Newtonsoft.Json;
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
Expand All @@ -15,17 +13,15 @@ namespace IsraelHiking.DataAccess
public class GraphHopperGateway : IGraphHopperGateway
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger _logger;
private readonly ConfigurationData _options;

public GraphHopperGateway(IHttpClientFactory httpClientFactory, IOptions<ConfigurationData> options, ILogger logger)
public GraphHopperGateway(IHttpClientFactory httpClientFactory, IOptions<ConfigurationData> options)
{
_httpClientFactory = httpClientFactory;
_options = options.Value;
_logger = logger;
}

public async Task<LineString> GetRouting(RoutingGatewayRequest request)
public async Task<Feature> GetRouting(RoutingGatewayRequest request)
{
var httpClient = _httpClientFactory.CreateClient();
string vehicle = "foot";
Expand All @@ -37,38 +33,38 @@ public async Task<LineString> GetRouting(RoutingGatewayRequest request)
case ProfileType.Bike:
vehicle = "bike2";
break;
case ProfileType.Car:
case ProfileType.Car4WheelDrive:
vehicle = "car4wd";
break;
case ProfileType.Car:
vehicle = "car";
break;
}
var requestAddress = $"{_options.GraphhopperServerAddress}route?instructions=false&points_encoded=false&elevation=true&point={request.From}&point={request.To}&vehicle={vehicle}";
var fromStr = $"{request.From.Y},{request.From.X}";
var toStr = $"{request.To.Y},{request.To.X}";
var requestAddress = $"{$"{_options.GraphhopperServerAddress}route?instructions=false&points_encoded=false&elevation=true&details=track_type&details=road_class&point="}{fromStr}&point={toStr}&vehicle={vehicle}";
var response = await httpClient.GetAsync(requestAddress);
var content = await response.Content.ReadAsStringAsync();
var jsonResponse = JsonConvert.DeserializeObject<JsonGraphHopperResponse>(content);
if (jsonResponse?.paths == null || !jsonResponse.paths.Any())
{
return new LineString(new Coordinate[0]); // CoordinateZ
return LineStringToFeature(new LineString(new[] { request.From, request.To }));
}
if (jsonResponse.paths.First().points.coordinates.Count == 1)
var path = jsonResponse.paths.First();
if (path.points.coordinates.Count == 1)
{
var jsonCoordinates = jsonResponse.paths.First().points.coordinates.First();
var jsonCoordinates = path.points.coordinates.First();
var convertedCoordiates = new CoordinateZ(jsonCoordinates[0], jsonCoordinates[1], jsonCoordinates.Count > 2 ? jsonCoordinates[2] : 0.0);
return new LineString(new[] { convertedCoordiates, convertedCoordiates });
return LineStringToFeature(new LineString(new[] { convertedCoordiates, convertedCoordiates }));
}
return new LineString(jsonResponse.paths.First().points.coordinates.Select(c => new CoordinateZ(c[0], c[1], c.Count > 2 ? c[2] : 0.0)).ToArray());
var lineString = new LineString(path.points.coordinates.Select(c => new CoordinateZ(c[0], c[1], c.Count > 2 ? c[2] : 0.0)).ToArray());
var table = new AttributesTable { { "details", path.details } };
return LineStringToFeature(lineString, table);
}

public async Task Rebuild(MemoryStream osmFileStream)
private Feature LineStringToFeature(LineString line, AttributesTable table = null)
{
_logger.LogInformation($"Starting creating graph hopper cache based on latest pbf file: {Sources.OSM_FILE_NAME}");
var httpClient = _httpClientFactory.CreateClient();
httpClient.Timeout = TimeSpan.FromMinutes(30);
var requestAddress = $"{_options.GraphhopperServerAddress}rebuild";
ByteArrayContent bytes = new ByteArrayContent(osmFileStream.ToArray());
MultipartFormDataContent multiContent = new MultipartFormDataContent();
multiContent.Add(bytes, "file", Sources.OSM_FILE_NAME);
await httpClient.PostAsync(requestAddress, multiContent);
_logger.LogInformation($"Finished creating graph hopper cache based on latest pbf file: {Sources.OSM_FILE_NAME}");
return new Feature(line, table ?? new AttributesTable());
}
}
}
2 changes: 0 additions & 2 deletions IsraelHiking.DataAccess/IsraelHiking.DataAccess.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@

<ItemGroup>
<PackageReference Include="CXuesong.MW.WikiClientLibrary" Version="0.7-int.6" />
<PackageReference Include="IsraelHiking.Elasticsearch" Version="5.6.3.1" />
<PackageReference Include="IsraelHiking.GPSBabel" Version="1.5.5-beta.3" />
<PackageReference Include="IsraelHiking.GPSBabel.Runtime.Windows" Version="1.5.5-beta.3" />
<PackageReference Include="IsraelHiking.GraphHopper" Version="0.10.0" />
<PackageReference Include="IsraelHiking.OsmCTools" Version="0.8.0" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.1" />
Expand Down
7 changes: 7 additions & 0 deletions IsraelHiking.DataAccess/JsonGraphHopperResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,18 @@ public class JsonPath
public long time { get; set; }
public bool points_encoded { get; set; }
public JsonPoints points { get; set; }
public JsonDetails details { get; set; }
}

public class JsonPoints
{
public string type { get; set; }
public List<List<double>> coordinates { get; set; }
}

public class JsonDetails
{
public List<List<string>> road_class { get; set; }
public List<List<string>> track_type { get; set; }
}
}
5 changes: 2 additions & 3 deletions IsraelHiking.DataAccessInterfaces/IGraphHopperGateway.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
using IsraelHiking.Common;
using System.Threading.Tasks;
using NetTopologySuite.Geometries;
using System.IO;
using NetTopologySuite.Features;

namespace IsraelHiking.DataAccessInterfaces
{
public interface IGraphHopperGateway
{
Task<LineString> GetRouting(RoutingGatewayRequest request);
Task Rebuild(MemoryStream osmFileStream);
Task<Feature> GetRouting(RoutingGatewayRequest request);
}
}
1 change: 0 additions & 1 deletion IsraelHiking.Web/IsraelHiking.Web.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@
<PackageReference Include="AspNetCore.Proxy" Version="3.1.1" />
<PackageReference Include="Codecov" Version="1.10.0" />
<PackageReference Include="CXuesong.MW.WikiClientLibrary" Version="0.7.0-int.6" />
<PackageReference Include="IsraelHiking.Elasticsearch" Version="5.6.3.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.1" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="3.1.1" />
Expand Down
3 changes: 2 additions & 1 deletion IsraelHiking.Web/appsettings.Production.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"Ortho": "C:\\Users\\osmhike\\Documents\\Maps\\Ortho2015",
"glyphs": "C:\\Users\\osmhike\\Documents\\GitHub\\orangemug\\font-glyphs\\glyphs"
},
"graphhopperServerAddress": "10.10.10.11:8989",
"proxiesDictionary": {
}
}
}
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ The technology stack of this site is base on the following frameworks:
* [Cordova](https://cordova.apache.org/) - Used to wrap the site as a mobile application and add some native capabilities
* [Redux using angular-redux](https://github.com/angular-redux/platform)
* [Dexie](https://dexie.org/) - Used for client side storage
* [Docker](https://www.docker.com/)

# Architecture and folder stucture of UI
The architecture is based heavily on Angular:
Expand All @@ -45,7 +46,7 @@ The architecture is based heavily on Angular:
* routers - handles the routing using server side - if server fails the none-router will be used.
* content - used for images and static content.
* environments - used for angular-cli to define production and dev variables.
* fonts - icomoon generated font for icons instead of images.
* fonts - [icomoon](https://icomoon.io/app/) generated font for icons instead of images.
* scss - used for global style files
* translations - all relevant data related to i18n

Expand All @@ -62,10 +63,11 @@ The architecture is based on layers
# Setting Up the Project for Development (Windows)
In order to be able to build this site you'll need some tools:
* Install [Java runtime](https://java.com/en/download/) - make sure to install 64bit version.
* Install [Docker](https://www.docker.com/products/docker-desktop)
* Download and install [Visual Studio community 2019](https://www.visualstudio.com/downloads) or later. Select:
* ASP.NET and web development
* .NET cross-platform development
* [.Net core SDK 3.0 ](https://www.microsoft.com/net/download/core)
* [.Net core SDK 3.1 ](https://www.microsoft.com/net/download/core)
* Install [node.js](https://nodejs.org/en/) for windows (10.1+). Use the recommended 64-bit installer on modern Windows versions.
* Open Visual Studio
* Follow [these steps](https://stackoverflow.com/a/43850262/368683) to update the version of node.js Visual Studio uses
Expand Down Expand Up @@ -104,8 +106,8 @@ In order to be able to make the server work a few prerequisits are needed:
* Windows machine with IIS enabled and a site (Although this site should be able to run on Linux it was never fully tested).
* Install Java Runtime Environment.
* Add `curl` to path.
* `GraphHopper.cmd` should be a process that run when the server machine starts and never die - use a watchdog or windows service to make sure they do (we use NSSM. for linux, check the java command inside those files and use a deamon to run them).
* Create a task to rebuild Graph Hopper and Elastic Search:
* For graphhoper routing see instructions here: https://github.com/IsraelHikingMap/graphhopper-docker
* Create a task to rebuild Elastic Search:
* Open Windows' Task Scheduler
* Create task
* Add an action to run `curl -k -X POST https://israelhiking.osm.org.il/api/update -d ""`
Expand Down
Loading

0 comments on commit d41a8c7

Please sign in to comment.