protected void HandleLineString(JSONArray lineStringCoordinates, IGeometryHandler handler) { handler.OnBeginLineString(); foreach (var pointCoordinates in lineStringCoordinates.Children) { HandlePoint(pointCoordinates.AsArray, handler); } handler.OnEndLineString(); }
/// <summary> /// Runs the tile task, resulting data will be stored in Data. /// </summary> /// <param name="featureCollections">The feature collections this tile task will be building.</param> public void Start(IEnumerable <FeatureCollection> featureCollections) { float inverseTileScale = 1.0f / (float)address.GetSizeMercatorMeters(); foreach (var styleLayer in featureStyling.Layers) { foreach (var collection in featureCollections) { foreach (var feature in styleLayer.GetFilter().Filter(collection)) { var layerStyle = styleLayer.Style; string featureName = ""; object identifier; if (feature.TryGetProperty("id", out identifier)) { featureName += identifier.ToString(); } // Resulting data for this feature. FeatureMesh featureMesh = new FeatureMesh(address.ToString(), collection.Name, styleLayer.Name, featureName); Debug.Log("^^^^^^^^^^^^^^^^^^--> 1 Tile: " + address.ToString()); Debug.Log("^^^^^^^^^^^^^^^^^^--> 2 Collection: " + collection.Name); Debug.Log("^^^^^^^^^^^^^^^^^^--> 3 Layer: " + styleLayer.Name); Debug.Log("^^^^^^^^^^^^^^^^^^--> 4 Identifier " + featureName); IGeometryHandler handler = null; if (feature.Type == GeometryType.Polygon || feature.Type == GeometryType.MultiPolygon) { var polygonOptions = layerStyle.GetPolygonOptions(feature, inverseTileScale); if (polygonOptions.Enabled) { handler = new PolygonBuilder(featureMesh.Mesh, polygonOptions, Transform); } } if (feature.Type == GeometryType.LineString || feature.Type == GeometryType.MultiLineString) { var polylineOptions = layerStyle.GetPolylineOptions(feature, inverseTileScale); if (polylineOptions.Enabled) { handler = new PolylineBuilder(featureMesh.Mesh, polylineOptions, Transform); } } if (handler != null) { feature.HandleGeometry(handler); data.Add(featureMesh); } } } } }
protected void HandlePolygon(JSONArray polygonCoordinates, IGeometryHandler handler) { handler.OnBeginPolygon(); foreach (var linearRingCoordinates in polygonCoordinates.Children) { handler.OnBeginLinearRing(); foreach (var pointCoordinates in linearRingCoordinates.Children) { HandlePoint(pointCoordinates.AsArray, handler); } handler.OnEndLinearRing(); } handler.OnEndPolygon(); }
public override bool HandleGeometry(IGeometryHandler handler) { var coordinates = geometryNode["coordinates"].AsArray; switch (Type) { case GeometryType.Point: HandlePoint(coordinates, handler); break; case GeometryType.MultiPoint: foreach (var point in coordinates.Children) { HandlePoint(point.AsArray, handler); } break; case GeometryType.LineString: HandleLineString(coordinates, handler); break; case GeometryType.MultiLineString: foreach (var lineString in coordinates.Children) { HandleLineString(lineString.AsArray, handler); } break; case GeometryType.Polygon: HandlePolygon(coordinates, handler); break; case GeometryType.MultiPolygon: foreach (var polygon in coordinates.Children) { HandlePolygon(polygon.AsArray, handler); } break; case GeometryType.Unknown: break; } return(true); }
public override bool HandleGeometry(IGeometryHandler handler) { var decoder = new GeometryDecoder(feature, layer); // From https://github.com/mapbox/vector-tile-spec/tree/master/2.1 // // The POINT geometry type encodes a point or multipoint geometry. The geometry command sequence for a point // geometry MUST consist of a single MoveTo command with a command count greater than 0. // // The LINESTRING geometry type encodes a linestring or multilinestring geometry. The geometry command sequence // for a linestring geometry MUST consist of one or more repetitions of the following sequence: // 1. A MoveTo command with a command count of 1 // 2. A LineTo command with a command count greater than 0 // // The POLYGON geometry type encodes a polygon or multipolygon geometry, each polygon consisting of exactly one // exterior ring that contains zero or more interior rings. The geometry command sequence for a polygon consists // of one or more repetitions of the following sequence: // 1. An ExteriorRing // 2. Zero or more InteriorRings // Each ExteriorRing and InteriorRing MUST consist of the following sequence: // 1. A MoveTo command with a command count of 1 // 2. A LineTo command with a command count greater than 1 // 3. A ClosePath command switch (feature.Type) { case PbfGeomType.Point: while (decoder.HasData()) { decoder.AdvanceCommand(); Debug.Assert(decoder.Command == CommandType.MoveTo && decoder.Repeat > 0); for (int i = decoder.Repeat; i > 0; i--) { handler.OnPoint(decoder.AdvanceCursor()); } } break; case PbfGeomType.LineString: while (decoder.HasData()) { handler.OnBeginLineString(); decoder.AdvanceCommand(); Debug.Assert(decoder.Command == CommandType.MoveTo && decoder.Repeat == 1); handler.OnPoint(decoder.AdvanceCursor()); decoder.AdvanceCommand(); Debug.Assert(decoder.Command == CommandType.LineTo && decoder.Repeat > 0); for (int i = decoder.Repeat; i > 0; i--) { handler.OnPoint(decoder.AdvanceCursor()); } handler.OnEndLineString(); } break; case PbfGeomType.Polygon: // Create temporary storage to hold rings until we determine whether they are interior or exterior. var ring = new List <Point>(); var isPolygonStarted = false; while (decoder.HasData()) { // Read out the coordinates of the next ring. decoder.AdvanceCommand(); Debug.Assert(decoder.Command == CommandType.MoveTo && decoder.Repeat == 1); ring.Add(decoder.AdvanceCursor()); decoder.AdvanceCommand(); for (int i = decoder.Repeat; i > 0; i--) { ring.Add(decoder.AdvanceCursor()); } ring.Add(ring.First()); decoder.AdvanceCommand(); Debug.Assert(decoder.Command == CommandType.ClosePath && decoder.Repeat == 1); // If ring is exterior, end the current polygon, start a new one, add ring to new polygon. // If ring is interior, add the ring to current polygon. var area = SignedArea(ring); if (area > 0) { if (isPolygonStarted) { handler.OnEndPolygon(); } handler.OnBeginPolygon(); isPolygonStarted = true; } handler.OnBeginLinearRing(); foreach (var point in ring) { handler.OnPoint(point); } handler.OnEndLinearRing(); ring.Clear(); } handler.OnEndPolygon(); break; case PbfGeomType.Unknown: return(false); } return(true); }
protected void HandlePoint(JSONArray pointCoordinates, IGeometryHandler handler) { var point = projectToLocalPoint(pointCoordinates[0].AsDouble, pointCoordinates[1].AsDouble); handler.OnPoint(point); }
public override bool HandleGeometry(IGeometryHandler handler) { var decoder = new GeometryDecoder(feature, layer); // From https://github.com/mapbox/vector-tile-spec/tree/master/2.1 // // The POINT geometry type encodes a point or multipoint geometry. The geometry command sequence for a point // geometry MUST consist of a single MoveTo command with a command count greater than 0. // // The LINESTRING geometry type encodes a linestring or multilinestring geometry. The geometry command sequence // for a linestring geometry MUST consist of one or more repetitions of the following sequence: // 1. A MoveTo command with a command count of 1 // 2. A LineTo command with a command count greater than 0 // // The POLYGON geometry type encodes a polygon or multipolygon geometry, each polygon consisting of exactly one // exterior ring that contains zero or more interior rings. The geometry command sequence for a polygon consists // of one or more repetitions of the following sequence: // 1. An ExteriorRing // 2. Zero or more InteriorRings // Each ExteriorRing and InteriorRing MUST consist of the following sequence: // 1. A MoveTo command with a command count of 1 // 2. A LineTo command with a command count greater than 1 // 3. A ClosePath command switch (feature.Type) { case PbfGeomType.Point: if (decoder.AdvanceCommand() && decoder.Command == CommandType.MoveTo) { for (int i = 0; i < decoder.Repeat; i++) { decoder.AdvanceCursor(); handler.OnPoint(decoder.CurrentPoint()); } } break; case PbfGeomType.LineString: while (decoder.AdvanceCommand() && (decoder.Command == CommandType.MoveTo && decoder.Repeat == 1)) { decoder.AdvanceCursor(); if (decoder.AdvanceCommand() && (decoder.Command == CommandType.LineTo && decoder.Repeat > 0)) { handler.OnBeginLineString(); handler.OnPoint(decoder.CurrentPoint()); for (int i = 0; i < decoder.Repeat; i++) { decoder.AdvanceCursor(); handler.OnPoint(decoder.CurrentPoint()); } handler.OnEndLineString(); } } break; case PbfGeomType.Polygon: while (decoder.AdvanceCommand() && (decoder.Command == CommandType.MoveTo && decoder.Repeat == 1)) { handler.OnBeginPolygon(); decoder.AdvanceCursor(); if (decoder.AdvanceCommand() && (decoder.Command == CommandType.LineTo && decoder.Repeat > 0)) { handler.OnBeginLinearRing(); var start = decoder.CurrentPoint(); handler.OnPoint(start); for (int i = 0; i < decoder.Repeat; i++) { decoder.AdvanceCursor(); handler.OnPoint(decoder.CurrentPoint()); } handler.OnPoint(start); handler.OnEndLinearRing(); } if (decoder.AdvanceCommand() && decoder.Command == CommandType.ClosePath) { // We should assert that this condition holds. } handler.OnEndPolygon(); } break; case PbfGeomType.Unknown: break; } return(true); }
/// <summary> /// Provides the geometry of this feature to a handler. /// </summary> /// <returns><c>true</c>, if geometry was handled completely with no errors, <c>false</c> otherwise.</returns> /// <param name="handler">The handler to receive the geometry events.</param> public abstract bool HandleGeometry(IGeometryHandler handler);