private VectorTileLayer ProcessPolygonTile(ISpatialDataSource spatialLayer, int tileX, int tileY, int zoom) { int tileSize = TileSize; RectangleD tileBounds = TileUtil.GetTileLatLonBounds(tileX, tileY, zoom, tileSize); //create a buffer around the tileBounds tileBounds.Inflate(tileBounds.Width * 0.05, tileBounds.Height * 0.05); int simplificationFactor = Math.Min(10, Math.Max(1, SimplificationPixelThreshold)); System.Drawing.Point tilePixelOffset = new System.Drawing.Point((tileX * tileSize), (tileY * tileSize)); using (IEnumerator <ISpatialData> data = spatialLayer.GetData(new BoundingBox() { MinX = tileBounds.Left, MinY = tileBounds.Top, MaxX = tileBounds.Right, MaxY = tileBounds.Bottom })) { GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds() { XMin = -20, YMin = -20, XMax = tileSize + 20, YMax = tileSize + 20 }; System.Drawing.Point[] pixelPoints = new System.Drawing.Point[1024]; System.Drawing.Point[] simplifiedPixelPoints = new System.Drawing.Point[1024]; PointD[] pointsBuffer = new PointD[1024]; List <System.Drawing.Point> clippedPolygon = new List <System.Drawing.Point>(); VectorTileLayer tileLayer = new VectorTileLayer(); tileLayer.Extent = (uint)tileSize; tileLayer.Version = 2; tileLayer.Name = spatialLayer.Name; while (data.MoveNext()) { ISpatialData spatialData = data.Current; VectorTileFeature feature = new VectorTileFeature() { Id = spatialData.Id, Geometry = new List <List <Coordinate> >(), Attributes = new List <AttributeKeyValue>(), GeometryType = Tile.GeomType.Polygon }; //get the point data var recordPoints = spatialData.Geometry; int partIndex = 0; foreach (PointD[] points in recordPoints) { //convert to pixel coordinates; if (pixelPoints.Length < points.Length) { pixelPoints = new System.Drawing.Point[points.Length + 10]; simplifiedPixelPoints = new System.Drawing.Point[points.Length + 10]; } for (int n = 0; n < points.Length; ++n) { Int64 x, y; TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize); pixelPoints[n].X = (int)(x - tilePixelOffset.X); pixelPoints[n].Y = (int)(y - tilePixelOffset.Y); } int outputCount = 0; SimplifyPointData(pixelPoints, null, points.Length, simplificationFactor, simplifiedPixelPoints, null, ref pointsBuffer, ref outputCount); if (outputCount > 1) { GeometryAlgorithms.PolygonClip(simplifiedPixelPoints, outputCount, clipBounds, clippedPolygon); if (clippedPolygon.Count > 0) { //output the clipped polygon List <Coordinate> lineString = new List <Coordinate>(); feature.Geometry.Add(lineString); for (int i = clippedPolygon.Count - 1; i >= 0; --i) { lineString.Add(new Coordinate(clippedPolygon[i].X, clippedPolygon[i].Y)); } } } ++partIndex; } //add the record attributes foreach (var keyValue in spatialData.Attributes) { feature.Attributes.Add(new AttributeKeyValue(keyValue.Key, keyValue.Value)); } if (feature.Geometry.Count > 0) { tileLayer.VectorTileFeatures.Add(feature); } } return(tileLayer); } }
private VectorTileLayer ProcessPointTile(ISpatialDataSource spatialLayer, int tileX, int tileY, int zoom) { int tileSize = TileSize; RectangleD tileBounds = TileUtil.GetTileLatLonBounds(tileX, tileY, zoom, tileSize); //create a buffer around the tileBounds tileBounds.Inflate(tileBounds.Width * 0.05, tileBounds.Height * 0.05); int simplificationFactor = Math.Min(10, Math.Max(1, SimplificationPixelThreshold)); System.Drawing.Point tilePixelOffset = new System.Drawing.Point((tileX * tileSize), (tileY * tileSize)); using (IEnumerator <ISpatialData> data = spatialLayer.GetData(new BoundingBox() { MinX = tileBounds.Left, MinY = tileBounds.Top, MaxX = tileBounds.Right, MaxY = tileBounds.Bottom })) { GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds() { XMin = -20, YMin = -20, XMax = tileSize + 20, YMax = tileSize + 20 }; VectorTileLayer tileLayer = new VectorTileLayer(); tileLayer.Extent = (uint)tileSize; tileLayer.Version = 2; tileLayer.Name = spatialLayer.Name; while (data.MoveNext()) { ISpatialData spatialData = data.Current; VectorTileFeature feature = new VectorTileFeature() { Id = spatialData.Id, Geometry = new List <List <Coordinate> >(), Attributes = new List <AttributeKeyValue>(), GeometryType = Tile.GeomType.Point }; //output the pixel coordinates List <Coordinate> coordinates = new List <Coordinate>(); var recordPoints = spatialData.Geometry; foreach (PointD[] points in recordPoints) { for (int n = 0; n < points.Length; ++n) { Int64 x, y; TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize); coordinates.Add(new Coordinate((int)(x - tilePixelOffset.X), (int)(y - tilePixelOffset.Y))); } } if (coordinates.Count > 0) { feature.Geometry.Add(coordinates); } //add the record attributes foreach (var keyValue in spatialData.Attributes) { feature.Attributes.Add(new AttributeKeyValue(keyValue.Key, keyValue.Value)); } if (feature.Geometry.Count > 0) { tileLayer.VectorTileFeatures.Add(feature); } } return(tileLayer); } }
private VectorTileLayer ProcessLineStringTile(ISpatialDataSource spatialLayer, int tileX, int tileY, int zoom) { int tileSize = TileSize; RectangleD tileBounds = TileUtil.GetTileLatLonBounds(tileX, tileY, zoom, tileSize); //create a buffer around the tileBounds tileBounds.Inflate(tileBounds.Width * 0.05, tileBounds.Height * 0.05); int simplificationFactor = Math.Min(10, Math.Max(1, SimplificationPixelThreshold)); System.Drawing.Point tilePixelOffset = new System.Drawing.Point((tileX * tileSize), (tileY * tileSize)); using (IEnumerator <ISpatialData> data = spatialLayer.GetData(new BoundingBox() { MinX = tileBounds.Left, MinY = tileBounds.Top, MaxX = tileBounds.Right, MaxY = tileBounds.Bottom })) { GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds() { XMin = -20, YMin = -20, XMax = tileSize + 20, YMax = tileSize + 20 }; bool outputMeasureValues = this.OutputMeasureValues && spatialLayer.HasMeasures; System.Drawing.Point[] pixelPoints = new System.Drawing.Point[1024]; System.Drawing.Point[] simplifiedPixelPoints = new System.Drawing.Point[1024]; double[] simplifiedMeasures = new double[1024]; PointD[] pointsBuffer = new PointD[1024]; VectorTileLayer tileLayer = new VectorTileLayer(); tileLayer.Extent = (uint)tileSize; tileLayer.Version = 2; tileLayer.Name = spatialLayer.Name; //int index = 0; //foreach (int index in indicies) while (data.MoveNext()) { ISpatialData spatialData = data.Current; VectorTileFeature feature = new VectorTileFeature() { Id = spatialData.Id, Geometry = new List <List <Coordinate> >(), Attributes = new List <AttributeKeyValue>() }; //get the point data var recordPoints = spatialData.Geometry; List <double[]> recordMeasures = null; if (outputMeasureValues) { recordMeasures = spatialData.Measures; } List <double> outputMeasures = new List <double>(); int partIndex = 0; foreach (PointD[] points in recordPoints) { double[] measures = recordMeasures != null ? recordMeasures[partIndex] : null; //convert to pixel coordinates; if (pixelPoints.Length < points.Length) { pixelPoints = new System.Drawing.Point[points.Length + 10]; simplifiedPixelPoints = new System.Drawing.Point[points.Length + 10]; simplifiedMeasures = new double[points.Length + 10]; } for (int n = 0; n < points.Length; ++n) { Int64 x, y; TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize); pixelPoints[n].X = (int)(x - tilePixelOffset.X); pixelPoints[n].Y = (int)(y - tilePixelOffset.Y); } int outputCount = 0; SimplifyPointData(pixelPoints, measures, points.Length, simplificationFactor, simplifiedPixelPoints, simplifiedMeasures, ref pointsBuffer, ref outputCount); //output count may be zero for short records at low zoom levels as //the pixel coordinates wil be a single point after simplification if (outputCount > 0) { List <int> clippedPoints = new List <int>(); List <int> parts = new List <int>(); if (outputMeasureValues) { List <double> clippedMeasures = new List <double>(); GeometryAlgorithms.PolyLineClip(simplifiedPixelPoints, outputCount, clipBounds, clippedPoints, parts, simplifiedMeasures, clippedMeasures); outputMeasures.AddRange(clippedMeasures); } else { GeometryAlgorithms.PolyLineClip(simplifiedPixelPoints, outputCount, clipBounds, clippedPoints, parts); } if (parts.Count > 0) { //output the clipped polyline for (int n = 0; n < parts.Count; ++n) { int index1 = parts[n]; int index2 = n < parts.Count - 1 ? parts[n + 1] : clippedPoints.Count; List <Coordinate> lineString = new List <Coordinate>(); feature.GeometryType = Tile.GeomType.LineString; feature.Geometry.Add(lineString); //clipped points store separate x/y pairs so there will be two values per measure for (int i = index1; i < index2; i += 2) { lineString.Add(new Coordinate(clippedPoints[i], clippedPoints[i + 1])); } } } } ++partIndex; } //add the record attributes foreach (var keyValue in spatialData.Attributes) { feature.Attributes.Add(new AttributeKeyValue(keyValue.Key, keyValue.Value)); } if (outputMeasureValues) { string s = Newtonsoft.Json.JsonConvert.SerializeObject(outputMeasures, new DoubleFormatConverter(4)); feature.Attributes.Add(new AttributeKeyValue(this.MeasuresAttributeName, s)); } if (feature.Geometry.Count > 0) { tileLayer.VectorTileFeatures.Add(feature); } } return(tileLayer); } }