Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
xivk committed Apr 5, 2022
1 parent 4ba582b commit 2f2f7ab
Show file tree
Hide file tree
Showing 12 changed files with 595 additions and 0 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Staging

on:
push:
branches: [ develop ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Add GitHub Nuget Source
run: dotnet nuget add source https://nuget.pkg.github.com/anyways-open/index.json -n anyways -u xivk -p ${{secrets.PACKAGES_SECRET }} --store-password-in-clear-text

- name: Setup .NET
uses: actions/setup-dotnet@v1
with:
dotnet-version: 6.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal

- name: Publish
run: dotnet publish -c release
working-directory: ./src/TilesMath/
- name: Nuget Pack
run: dotnet pack -c release --version-suffix dev
working-directory: ./src/TilesMath/
- name: Nuget Push
run: dotnet nuget push **/*.nupkg --skip-duplicate -k ${{ secrets.GITHUB_TOKEN }} -s https://nuget.pkg.github.com/anyways-open/index.json
working-directory: ./src/
54 changes: 54 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
[Oo]bj
[Bb]in
*.user
*.suo
*.[Cc]ache
*.bak
*.ncb
*.log
*.DS_Store
[Tt]humbs.db
_ReSharper.*
*.resharper
Ankh.NoLoad
Core/Output*/
UI/Output*/
UI/WinForms/Output*/
Data/Oracle/Output*/
Data/PostgreSQL/Output*/
Data/Redis/Output*/
Data/SQLServer/Output*/
Data/SQLite/Output*/
Core/OsmSharp.UnitTests/test-results*/
*.userprefs
Output*/
OutputAndroid*/
OutputWindowsPhone*/
*.psess
test-results*/
*.vsp
.DotSettings
*.vspx
*.patch
TestResults*/

packages/*
!packages/repositories.config
.vs/*

TestResult*.xml
*.routerdb
*.osm.pbf

*.shp
*.dbf
*.shx
.idea/*
*.geojson
*.tile
*.tile.zip
*.hgt.zip
**/logs/*
**/elevation-cache/

src/ANYWAYS.Routing.API/logs/
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# tiles-math

A tiny library to share tile schema calculations.
27 changes: 27 additions & 0 deletions TilesMath.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30114.105
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{61289184-772B-4826-B7A0-1249F00A7FDD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TilesMath", "src\TilesMath\TilesMath.csproj", "{0D1D5A4A-C7E1-4B92-87DA-E5FC8F544904}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0D1D5A4A-C7E1-4B92-87DA-E5FC8F544904}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0D1D5A4A-C7E1-4B92-87DA-E5FC8F544904}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D1D5A4A-C7E1-4B92-87DA-E5FC8F544904}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D1D5A4A-C7E1-4B92-87DA-E5FC8F544904}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{0D1D5A4A-C7E1-4B92-87DA-E5FC8F544904} = {61289184-772B-4826-B7A0-1249F00A7FDD}
EndGlobalSection
EndGlobal
86 changes: 86 additions & 0 deletions src/TilesMath/GlobalTileId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
namespace TilesMath;

internal static class GlobalTileId
{
private static long ForZoom(int zoom)
{
switch (zoom)
{
case 0:
// zoom level 0: {0}.
return 0;
case 1:
return 1;
case 2:
return 5;
case 3:
return 21;
case 4:
return 85;
case 5:
return 341;
case 6:
return 1365;
case 7:
return 5461;
case 8:
return 21845;
case 9:
return 87381;
case 10:
return 349525;
case 11:
return 1398101;
case 12:
return 5592405;
case 13:
return 22369621;
case 14:
return 89478485;
case 15:
return 357913941;
case 16:
return 1431655765;
case 17:
return 5726623061;
case 18:
return 22906492245;
}

var xMax = 1 << zoom;
var tileId = ForZoom(zoom - 1) + xMax;
return tileId;
}

internal static (int x, int y, int zoom) From(long globalTileId)
{
// find out the zoom level first.
var zoom = 0;
if (globalTileId > 0)
{
// only if the id is at least at zoom level 1.
while (globalTileId >= ForZoom(zoom))
{
// move to the next zoom level and keep searching.
zoom++;
}

zoom--;
}

// calculate the x-y.
var local = globalTileId - ForZoom(zoom);
var width = 1 << zoom;
var x = (int)(local % width);
var y = (int)(local / width);

return (x, y, zoom);
}

internal static long ForTile(Tile tile)
{
var xMax = 1 << tile.Zoom;

return ForZoom(tile.Zoom) + tile.Y * xMax + tile.X;
}
}
27 changes: 27 additions & 0 deletions src/TilesMath/LocalTileId.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace TilesMath;

internal static class LocalTileId
{
internal static (int x, int y) From(int localId, int zoom)
{
var xMax = 1 << zoom;

var x = localId % xMax;
var y = localId / xMax;
return (x, y);
}

internal static int Max(int zoom)
{
var xMax = 1 << zoom;

return xMax * xMax;
}

internal static int ForTile(Tile tile)
{
var xMax = 1 << (int)tile.Zoom;

return tile.Y * xMax + tile.X;
}
}
122 changes: 122 additions & 0 deletions src/TilesMath/Tile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using System.Runtime.CompilerServices;

namespace TilesMath;

/// <summary>
/// Represents a tile.
/// </summary>
public readonly struct Tile
{
private Tile(int x, int y, byte zoom)
{
this.X = x;
this.Y = y;
this.Zoom = zoom;
}

/// <summary>
/// The x-coordinate.
/// </summary>
public int X { get; } = -1;

/// <summary>
/// The y-coordinate.
/// </summary>
public int Y { get; } = -1;

/// <summary>
/// The zoom-level.
/// </summary>
public byte Zoom { get; }

/// <summary>
/// Returns true if this tile is empty.
/// </summary>
public bool IsEmpty => this.X == -1 || this.Y == -1;

/// <summary>
/// The local id.
/// </summary>
public int LocalId => LocalTileId.ForTile(this);

/// <summary>
/// The global id.
/// </summary>
public long GlobalId => GlobalTileId.ForTile(this);

/// <summary>
/// The tile boundaries.
/// </summary>
public TileBounds Boundaries => TileGeo.BoundariesFor(this);

/// <summary>
/// The neighbours.
/// </summary>
public TileNeighbours Neighbours => new TileNeighbours(this);

/// <summary>
/// Creates a new tile from x-y coordinate and zoom level.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="zoom"></param>
/// <returns></returns>
public static Tile Create(int x, int y, int zoom)
{
return new Tile(x, y, (byte)zoom);
}

/// <summary>
/// Creates a new tile from its global id.
/// </summary>
/// <param name="globalId">The global id.</param>
/// <returns>The tile equivalent to the global id.</returns>
public static Tile FromGlobalId(long globalId)
{
var (x, y, z) = GlobalTileId.From(globalId);

return new Tile(x, y, (byte)z);
}

/// <summary>
/// Creates a new tile from its local id.
/// </summary>
/// <param name="localId">The local id.</param>
/// <param name="zoom"></param>
/// <returns>The tile equivalent to for the local id at the given zoom level.</returns>
public static Tile FromLocalId(int localId, int zoom)
{
var (x, y) = LocalTileId.From(localId, zoom);

return new Tile(x, y, (byte)zoom);
}

/// <summary>
/// Calculates the maximum local id for the given zoom level.
/// </summary>
/// <param name="zoom">The zoom level.</param>
/// <returns>The maximum local id for the given zoom level</returns>
public static int MaxLocalId(int zoom)
{
return LocalTileId.Max(zoom);
}

/// <summary>
/// Creates the tile at the given WGS84 coordinates and zoom level.
/// </summary>
/// <param name="longitude">The longitude.</param>
/// <param name="latitude">The latitude.</param>
/// <param name="zoom">The zoom-level.</param>
/// <returns>The tile at the given location and zoom level.</returns>
public static Tile AtLocation(double longitude, double latitude, int zoom)
{
var (x, y) = TileGeo.ForLocation(longitude, latitude, zoom);

return new Tile(x, y, (byte)zoom);
}

/// <summary>
/// Creates an empty tile.
/// </summary>
public static Tile Empty = new Tile(-1, -1, 0);
}
Loading

0 comments on commit 2f2f7ab

Please sign in to comment.