private static TileLayer ProcessTile(FeatureLayer featureLayer, int tileX, int tileY, int zoom, IEnumerable <string> columnNames, int simplificationFactor, int tileSize) { RectangleShape tileBoundingBox = GetTileSphericalMercatorBoundingBox(tileX, tileY, zoom, tileSize); RectangleShape scaledUpBoudingBox = new RectangleShape(tileBoundingBox.GetWellKnownBinary()); scaledUpBoudingBox.ScaleUp(5); featureLayer.Open(); Collection <string> allFeatureIds = featureLayer.FeatureSource.GetFeatureIdsInsideBoundingBox(scaledUpBoudingBox); RectangleInt tileScreenBoundingBox = new RectangleInt() { XMin = -20, YMin = -20, XMax = tileSize + 20, YMax = tileSize + 20 }; TileLayer tileLayer = new TileLayer(); tileLayer.Extent = (uint)tileSize; tileLayer.Version = 2; tileLayer.Name = featureLayer.Name; int IdsCountToExecute = allFeatureIds.Count; int startIndex = 0; while (IdsCountToExecute > 0) { List <string> featureIds = GetSubString(allFeatureIds, startIndex, Math.Min(1000, IdsCountToExecute)); IdsCountToExecute = IdsCountToExecute - featureIds.Count; startIndex = startIndex + featureIds.Count; Collection <Feature> features = GetFeaturesByIds(featureLayer, featureIds, columnNames); foreach (Feature feature in features) { TileFeature tileFeature = GetVectorTileFeature(feature, zoom, tileSize, tileScreenBoundingBox, simplificationFactor, tileBoundingBox); if (tileFeature.Geometry.Count > 0) { tileLayer.Features.Add(tileFeature); } } } tileLayer.FillInTheInternalProperties(); return(tileLayer); }
private static void ProcessRingShape(int zoom, int tileSize, RectangleInt tileScreenBoundingBox, TileFeature tileFeature, RingShape ringShape, int simplificationFactor, RectangleShape tileBoundingBox) { PointInt[] tilePoints = new PointInt[ringShape.Vertices.Count]; for (int n = 0; n < ringShape.Vertices.Count; ++n) { tilePoints[n] = WorldPointToTilePoint(ringShape.Vertices[n].X, ringShape.Vertices[n].Y, zoom, tileSize, tileBoundingBox); } PointInt[] simplifiedTilePoints = SimplifyPointData(tilePoints, simplificationFactor); //output count may be zero for short records at low zoom levels as //the pixel coordinates wil be a single point after simplification if (simplifiedTilePoints.Length > 3) { if (simplifiedTilePoints[0] != simplifiedTilePoints[simplifiedTilePoints.Length - 1]) { Console.WriteLine("Not Closed"); } List <PointInt> clippedRing = ClipRingShape(simplifiedTilePoints, tileScreenBoundingBox); if (clippedRing.Count > 3) { tileFeature.Geometry.Add(clippedRing); } } }
private static void ProcessLineShape(int zoom, int tileSize, RectangleInt tileScreenBoundingBox, TileFeature tileFeature, MultilineShape multiLineShape, int simplificationFactor, RectangleShape tileBoundingBox) { foreach (LineShape line in multiLineShape.Lines) { PointInt[] pixelPoints = new PointInt[line.Vertices.Count]; for (int n = 0; n < line.Vertices.Count; ++n) { pixelPoints[n] = WorldPointToTilePoint(line.Vertices[n].X, line.Vertices[n].Y, zoom, tileSize, tileBoundingBox); } PointInt[] simplifiedPixelPoints = SimplifyPointData(pixelPoints, simplificationFactor); //output count may be zero for short records at low zoom levels as //the pixel coordinates wil be a single point after simplification if (simplifiedPixelPoints.Length > 0) { List <int> clippedPoints = new List <int>(); List <int> parts = new List <int>(); ClipPolyline(simplifiedPixelPoints, tileScreenBoundingBox, 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 <PointInt> lineString = new List <PointInt>(); tileFeature.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 PointInt(clippedPoints[i], clippedPoints[i + 1])); } } } } } }
private static TileFeature GetVectorTileFeature(Feature feature, int zoom, int tileSize, RectangleInt tileScreenBoundingBox, int simplificationFactor, RectangleShape tileBoundingBox) { TileFeature tileFeature = new TileFeature(); switch (feature.GetWellKnownType()) { case WellKnownType.Line: case WellKnownType.Multiline: tileFeature.Type = GeometryType.LineString; MultilineShape multiLineShape = new MultilineShape(feature.GetWellKnownBinary()); ProcessLineShape(zoom, tileSize, tileScreenBoundingBox, tileFeature, multiLineShape, simplificationFactor, tileBoundingBox); break; case WellKnownType.Polygon: case WellKnownType.Multipolygon: tileFeature.Type = GeometryType.Polygon; MultipolygonShape multiPolygonShape = new MultipolygonShape(feature.GetWellKnownBinary()); foreach (PolygonShape polygonShape in multiPolygonShape.Polygons) { ProcessRingShape(zoom, tileSize, tileScreenBoundingBox, tileFeature, polygonShape.OuterRing, simplificationFactor, tileBoundingBox); foreach (RingShape ringShape in polygonShape.InnerRings) { ProcessRingShape(zoom, tileSize, tileScreenBoundingBox, tileFeature, ringShape, simplificationFactor, tileBoundingBox); } } break; case WellKnownType.Point: case WellKnownType.Multipoint: tileFeature.Type = GeometryType.Point; List <PointInt> coordinates = new List <PointInt>(); MultipointShape multiPointShape = new MultipointShape(); if (feature.GetWellKnownType() == WellKnownType.Point) { PointShape pointShape = new PointShape(feature.GetWellKnownBinary()); multiPointShape.Points.Add(pointShape); } else if (feature.GetWellKnownType() == WellKnownType.Multipoint) { multiPointShape = new MultipointShape(feature.GetWellKnownBinary()); } foreach (PointShape point in multiPointShape.Points) { PointInt pointI = WorldPointToTilePoint(point.X, point.Y, zoom, tileSize, tileBoundingBox); coordinates.Add(new PointInt(pointI.X, pointI.Y)); } if (coordinates.Count > 0) { tileFeature.Geometry.Add(coordinates); } break; default: tileFeature.Type = GeometryType.Unknown; break; } //add the record attributes foreach (var attributes in feature.ColumnValues) { tileFeature.Attributes.Add(new TileAttribute(attributes.Key, attributes.Value)); } return(tileFeature); }