Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ TestResults/
StyleCop.Cache
nuget.exe
.vscode/
.vs/
tools/

# globs
Expand Down
10 changes: 8 additions & 2 deletions src/DemoConsoleApp/program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public static int Main(string[] args)
{

string vtIn = string.Empty;
bool validate = true;
uint? clipBuffer = null;
bool outGeoJson = false;
ulong? zoom = null;
Expand All @@ -41,6 +42,10 @@ public static int Main(string[] args)
{
parseArg(argLow.Replace("tileid:", ""), out zoom, out tileCol, out tileRow);
}
else if (argLow.Contains("validate:"))
{
validate = argLow.Replace("validate:", "").Equals("true");
}
}

if (!File.Exists(vtIn))
Expand All @@ -62,7 +67,7 @@ public static int Main(string[] args)

var bufferedData = File.ReadAllBytes(vtIn);

VectorTile tile = new VectorTile(bufferedData);
VectorTile tile = new VectorTile(bufferedData, validate);

if (outGeoJson)
{
Expand All @@ -79,7 +84,7 @@ public static int Main(string[] args)
for (int i = 0; i < featCnt; i++)
{
VectorTileFeature feat = lyr.GetFeature(i, clipBuffer);
Console.WriteLine(string.Format("feature {0}: {1}", i, feat.GeometryType));
Console.WriteLine(string.Format("feature[{0}] id:{1} geomtype:{2}", i, feat.Id, feat.GeometryType));
Dictionary<string, object> props = feat.GetProperties();
foreach (var prop in props)
{
Expand All @@ -99,6 +104,7 @@ private static void usage()
Console.WriteLine("DemoConsoleApp.exe vt:<tile.mvt> <other parameters>");
Console.WriteLine("");
Console.WriteLine("- vt:<path/to/vector/tile.mvt> or vt:<path/to/<z>-<x>-<y>.tile.mvt>");
Console.WriteLine("- validate:<true|false> validate vt contents, default:true");
Console.WriteLine("- clip:<buffer> to clip geometries extending beyong the tile border");
Console.WriteLine("- out:<geojson|metadata> to ouput either GeoJson or some metadata");
Console.WriteLine("- tileid:<z>-<x>-<y> to pass tile id if not contained within the file name");
Expand Down
4 changes: 4 additions & 0 deletions src/VectorTileReader/VectorTileFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public class VectorTileFeature
/// <param name="layer">Parent <see cref="VectorTileLayer"/></param>
public VectorTileFeature(VectorTileLayer layer, uint? clipBuffer = null, float scale = 1.0f)
{
//set some defaults according to the spec: https://github.com/mapbox/vector-tile-spec/blob/master/2.1/vector_tile.proto
Id = 0;
GeometryType = GeomType.UNKNOWN;

_layer = layer;
_clipBuffer = clipBuffer;
_scale = scale;
Expand Down
4 changes: 4 additions & 0 deletions src/VectorTileReader/VectorTileLayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public class VectorTileLayer
/// </summary>
public VectorTileLayer()
{
//set some defaults according to the spec: https://github.com/mapbox/vector-tile-spec/blob/master/2.1/vector_tile.proto
Version = 1;
Extent = 4096;

_FeaturesData = new List<byte[]>();
Keys = new List<string>();
Values = new List<object>();
Expand Down
16 changes: 14 additions & 2 deletions src/VectorTileReader/VectorTileReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ public VectorTileReader(byte[] data, bool validate = true)
}
if (data[0] == 0x1f && data[1] == 0x8b)
{
throw new System.Exception("Tile data is zipped");
throw new System.Exception("Tile data is gzipped");
}
if (data[0] == 0x78 && (data[1] == 0x9C || data[1] == 0x01 || data[1] == 0xDA || data[1] == 0x5E))
{
throw new System.Exception("Tile data is zlib compressed");
}

_Validate = validate;
Expand Down Expand Up @@ -239,13 +243,21 @@ private VectorTileLayer getLayer(byte[] data)
{
throw new System.Exception(string.Format("Layer [{0}] has no extent.", layer.Name));
}

//commenting following check as per
//"Layer has no features, encoders should not create this, but decoders should read this still"
//https://github.com/mapbox/mvt-fixtures/blob/7e0e67ba67478fd8af63509077b000ee5cee2d6d/fixtures/025/info.json#L2
/*
if (0 == layer.FeatureCount())
{
throw new System.Exception(string.Format("Layer [{0}] has no features.", layer.Name));
}
*/

//TODO: find equivalent of 'Distinct()' for NET20
#if !NET20
if (layer.Values.Count != layer.Values.Distinct().Count()) {
if (layer.Values.Count != layer.Values.Distinct().Count())
{
throw new System.Exception(string.Format("Layer [{0}]: duplicate attribute values found", layer.Name));
}
#endif
Expand Down
136 changes: 136 additions & 0 deletions src/VectorTiles.Tests/TestAllMVTs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using System;
using System.IO;
using Mapbox.VectorTile;
using System.Collections;
using Newtonsoft.Json.Linq;
#if WINDOWS_UWP
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using ATestClass = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestClassAttribute;
using ATestMethod = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestMethodAttribute;
using ATestClassSetup = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.ClassInitializeAttribute; //run once per class
using ATestSetup = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.TestInitializeAttribute; //run before every test
using ATestDataSource = Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceAttribute;
#else
using NUnit.Framework;
using ATestClass = NUnit.Framework.TestFixtureAttribute;
using ATestMethod = NUnit.Framework.TestAttribute;
using ATestClassSetup = NUnit.Framework.OneTimeSetUpAttribute;
using ATestDataSource = NUnit.Framework.TestCaseSourceAttribute;
#endif


namespace VectorTiles.Tests
{


[ATestClass]
public class BulkMvtTests
{

private string _fixturesPath;
public static string _executingFolder = AppDomain.CurrentDomain.BaseDirectory;


[ATestClassSetup]
protected void SetUp()
{
_fixturesPath = Path.Combine(_executingFolder, "..", "test", "mvt-fixtures", "fixtures");
}

[ATestMethod, Order(1)]
public void FixturesPathExists()
{
Assert.True(Directory.Exists(_fixturesPath), "MVT fixtures directory exists");
}


[ATestMethod, ATestDataSource(typeof(GetMVTs), "GetValidFixtureFileNames")]
public void ValidMvt(string fileName)
{
Assert.True(File.Exists(fileName), "Vector tile exists");
byte[] data = File.ReadAllBytes(fileName);
Assert.DoesNotThrow(() =>
{
VectorTile vt = new VectorTile(data);
foreach (var layerName in vt.LayerNames())
{
var layer = vt.GetLayer(layerName);
for (int i = 0; i < layer.FeatureCount(); i++)
{
var feat = layer.GetFeature(i);
feat.GetProperties();
}
}
});
}


[ATestMethod, ATestDataSource(typeof(GetMVTs), "GetInvalidFixtureFileNames")]
public void InvalidMvt(string fileName)
{
Assert.True(File.Exists(fileName), "Vector tile exists");
byte[] data = File.ReadAllBytes(fileName);
bool didThrow = true;
Assert.Throws(Is.InstanceOf<Exception>(), () =>
{
VectorTile vt = new VectorTile(data);
foreach (var layerName in vt.LayerNames())
{
var layer = vt.GetLayer(layerName);
for (int i = 0; i < layer.FeatureCount(); i++)
{
var feat = layer.GetFeature(i);
feat.GetProperties();
}
}
didThrow = false;
});
Assert.True(didThrow);
}


}




public partial class GetMVTs
{
public static IEnumerable GetValidFixtureFileNames()
{
foreach (var testCase in getFixtureFileNames(true))
{
yield return testCase;
}
}

public static IEnumerable GetInvalidFixtureFileNames()
{
foreach (var testCase in getFixtureFileNames(false))
{
yield return testCase;
}
}

private static IEnumerable getFixtureFileNames(bool valid)
{
string path = Path.Combine(BulkMvtTests._executingFolder, "..", "test", "mvt-fixtures", "fixtures");

foreach (var fixtureDir in Directory.GetDirectories(path))
{
string infoJson = Path.Combine(fixtureDir, "info.json");
if (!File.Exists(infoJson)) { continue; }
dynamic info = JObject.Parse(File.ReadAllText(infoJson));
if (info.validity.v2 != valid) { continue; }
yield return new TestCaseData(Path.Combine(fixtureDir, "tile.mvt"));
}
}


}





}
62 changes: 0 additions & 62 deletions src/VectorTiles.Tests/TestGeometry.cs

This file was deleted.

Loading