Пример #1
0
        private VectorTileLayer ProcessPointTile(ShapeFile shapeFile, int tileX, int tileY, int zoom, OutputTileFeatureDelegate outputTileFeature)
        {
            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));

            List <int> indicies = new List <int>();

            shapeFile.GetShapeIndiciesIntersectingRect(indicies, tileBounds);
            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    = !string.IsNullOrEmpty(shapeFile.Name) ? shapeFile.Name : System.IO.Path.GetFileNameWithoutExtension(shapeFile.FilePath);

            if (indicies.Count > 0)
            {
                foreach (int index in indicies)
                {
                    if (outputTileFeature != null && !outputTileFeature(shapeFile, index, zoom, tileX, tileY))
                    {
                        continue;
                    }

                    VectorTileFeature feature = new VectorTileFeature()
                    {
                        Id           = index.ToString(System.Globalization.CultureInfo.InvariantCulture),
                        Geometry     = new List <List <Coordinate> >(),
                        Attributes   = new List <AttributeKeyValue>(),
                        GeometryType = Tile.GeomType.Point
                    };

                    //output the pixel coordinates
                    List <Coordinate> coordinates = new List <Coordinate>();
                    //get the point data
                    var recordPoints = shapeFile.GetShapeDataD(index);
                    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
                    string[] fieldNames = shapeFile.GetAttributeFieldNames();
                    string[] values     = shapeFile.GetAttributeFieldValues(index);
                    for (int n = 0; n < values.Length; ++n)
                    {
                        feature.Attributes.Add(new AttributeKeyValue(fieldNames[n], values[n].Trim()));
                    }

                    if (feature.Geometry.Count > 0)
                    {
                        tileLayer.VectorTileFeatures.Add(feature);
                    }
                }
            }

            return(tileLayer);
        }
Пример #2
0
        private VectorTileLayer ProcessPolygonTile(ShapeFile shapeFile, int tileX, int tileY, int zoom, OutputTileFeatureDelegate outputTileFeature)
        {
            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));

            List <int> indicies = new List <int>();

            shapeFile.GetShapeIndiciesIntersectingRect(indicies, tileBounds);
            GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds()
            {
                XMin = -20,
                YMin = -20,
                XMax = tileSize + 20,
                YMax = tileSize + 20
            };

            List <System.Drawing.Point> clippedPolygon = new List <System.Drawing.Point>();


            VectorTileLayer tileLayer = new VectorTileLayer();

            tileLayer.Extent  = (uint)tileSize;
            tileLayer.Version = 2;
            tileLayer.Name    = !string.IsNullOrEmpty(shapeFile.Name) ? shapeFile.Name : System.IO.Path.GetFileNameWithoutExtension(shapeFile.FilePath);

            if (indicies.Count > 0)
            {
                foreach (int index in indicies)
                {
                    if (outputTileFeature != null && !outputTileFeature(shapeFile, index, zoom, tileX, tileY))
                    {
                        continue;
                    }

                    VectorTileFeature feature = new VectorTileFeature()
                    {
                        Id           = index.ToString(System.Globalization.CultureInfo.InvariantCulture),
                        Geometry     = new List <List <Coordinate> >(),
                        Attributes   = new List <AttributeKeyValue>(),
                        GeometryType = Tile.GeomType.Polygon
                    };

                    //get the point data
                    var recordPoints = shapeFile.GetShapeDataD(index);
                    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];
                        }
                        int pointCount = 0;
                        for (int n = 0; n < points.Length; ++n)
                        {
                            Int64 x, y;
                            TileUtil.LLToPixel(points[n], zoom, out x, out y, tileSize);

                            pixelPoints[pointCount].X   = (int)(x - tilePixelOffset.X);
                            pixelPoints[pointCount++].Y = (int)(y - tilePixelOffset.Y);
                        }
                        ////check for duplicates points at end after they have been converted to pixel coordinates
                        ////polygons need at least 3 points so don't reduce less than this
                        //while(pointCount > 3 && (pixelPoints[pointCount-1] == pixelPoints[pointCount - 2]))
                        //{
                        //    --pointCount;
                        //}

                        int outputCount = 0;
                        SimplifyPointData(pixelPoints, null, pointCount, simplificationFactor, simplifiedPixelPoints, null, ref pointsBuffer, ref outputCount);
                        //simplifiedPixelPoints[outputCount++] = pixelPoints[pointCount-1];

                        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
                    string[] fieldNames = shapeFile.GetAttributeFieldNames();
                    string[] values     = shapeFile.GetAttributeFieldValues(index);
                    for (int n = 0; n < values.Length; ++n)
                    {
                        feature.Attributes.Add(new AttributeKeyValue(fieldNames[n], values[n].Trim()));
                    }

                    if (feature.Geometry.Count > 0)
                    {
                        tileLayer.VectorTileFeatures.Add(feature);
                    }
                }
            }

            return(tileLayer);
        }
Пример #3
0
        private VectorTileLayer ProcessLineStringTile(ShapeFile shapeFile, int tileX, int tileY, int zoom, OutputTileFeatureDelegate outputTileFeature)
        {
            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));

            List <int> indicies = new List <int>();

            shapeFile.GetShapeIndiciesIntersectingRect(indicies, tileBounds);
            GeometryAlgorithms.ClipBounds clipBounds = new GeometryAlgorithms.ClipBounds()
            {
                XMin = -20,
                YMin = -20,
                XMax = tileSize + 20,
                YMax = tileSize + 20
            };
            bool outputMeasureValues = this.OutputMeasureValues && (shapeFile.ShapeType == ShapeType.PolyLineM || shapeFile.ShapeType == ShapeType.PolyLineZ);

            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    = !string.IsNullOrEmpty(shapeFile.Name) ? shapeFile.Name : System.IO.Path.GetFileNameWithoutExtension(shapeFile.FilePath);

            if (indicies.Count > 0)
            {
                foreach (int index in indicies)
                {
                    if (outputTileFeature != null && !outputTileFeature(shapeFile, index, zoom, tileX, tileY))
                    {
                        continue;
                    }

                    VectorTileFeature feature = new VectorTileFeature()
                    {
                        Id         = index.ToString(System.Globalization.CultureInfo.InvariantCulture),
                        Geometry   = new List <List <Coordinate> >(),
                        Attributes = new List <AttributeKeyValue>()
                    };

                    //get the point data
                    var recordPoints = shapeFile.GetShapeDataD(index);
                    System.Collections.ObjectModel.ReadOnlyCollection <double[]> recordMeasures = null;

                    if (outputMeasureValues)
                    {
                        recordMeasures = shapeFile.GetShapeMDataD(index);
                    }

                    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
                    string[] fieldNames = shapeFile.GetAttributeFieldNames();
                    string[] values     = shapeFile.GetAttributeFieldValues(index);
                    for (int n = 0; n < values.Length; ++n)
                    {
                        feature.Attributes.Add(new AttributeKeyValue(fieldNames[n], values[n].Trim()));
                    }
                    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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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);
            }
        }