Example #1
0
        private void ExtractTiles(PolygonShape polygonShape, string targetFilePath)
        {
            RectangleShape         bbox       = polygonShape.GetBoundingBox();
            List <VectorTileRange> tileRanges = new List <VectorTileRange>();

            for (int zoomLevel = 0; zoomLevel <= maxZoom; zoomLevel++)
            {
                VectorTileRange tileRange = GetTileRange(zoomLevel, bbox);
                tileRanges.Add(tileRange);
            }
            ThinkGeoMBTilesLayer.CreateDatabase(targetFilePath);

            var targetDBConnection = new SqliteConnection($"Data Source={targetFilePath}");

            targetDBConnection.Open();
            var targetMap      = new TilesTable(targetDBConnection);
            var targetMetadata = new MetadataTable(targetDBConnection);

            var sourceDBConnection = new SqliteConnection($"Data Source={mbtilesPathFilename}");

            sourceDBConnection.Open();
            var sourceMap      = new TilesTable(sourceDBConnection);
            var sourceMetadata = new MetadataTable(sourceDBConnection);

            sourceMetadata.ReadAllEntries();

            ProjectionConverter projection = new ProjectionConverter(3857, 4326);

            projection.Open();
            var wgs84BBox = projection.ConvertToExternalProjection(bbox);

            foreach (MetadataEntry entry in sourceMetadata.Entries)
            {
                if (entry.Name.Equals("center"))
                {
                    PointShape centerPoint = wgs84BBox.GetCenterPoint();
                    entry.Value = $"{centerPoint.X},{centerPoint.Y},{maxZoom}";
                }
                else if (entry.Name.Equals("bounds"))
                {
                    entry.Value = $"{wgs84BBox.UpperLeftPoint.X},{wgs84BBox.UpperLeftPoint.Y},{wgs84BBox.LowerRightPoint.X},{wgs84BBox.LowerRightPoint.Y}";
                }
            }
            targetMetadata.Insert(sourceMetadata.Entries);

            int recordLimit = 1000;

            foreach (var tileRange in tileRanges)
            {
                long offset = 0;
                bool isEnd  = false;
                while (!isEnd)
                {
                    string querySql = $"SELECT * FROM {sourceMap.TableName} WHERE " + ConvetToSqlString(tileRange) + $" LIMIT {offset},{recordLimit}";
                    var    entries  = sourceMap.Query(querySql);
                    for (int i = entries.Count - 1; i >= 0; i--)
                    {
                        RectangleShape pbfExtent = GetPbfTileExent((int)entries[i].ZoomLevel, entries[i].TileColumn, entries[i].TileRow);
                        if (polygonShape.IsDisjointed(pbfExtent))
                        {
                            entries.RemoveAt(i);
                        }
                    }
                    targetMap.Insert(entries);

                    if (entries.Count < recordLimit)
                    {
                        isEnd = true;
                    }

                    offset = offset + recordLimit;
                }
            }
        }