private void RadioButton_Checked(object sender, RoutedEventArgs e) { if (CheckBoxDisableRasterCache != null && thinkGeoMBTilesFeatureLayer != null) { Uri styleJsonUri = thinkGeoMBTilesFeatureLayer.StyleJsonUri; string senderName = (sender as RadioButton).Name; if (senderName == "RadioButtonLight") { styleJsonUri = new Uri(SampleHelper.Get("thinkgeo-world-streets-light.json"), UriKind.Relative); } else if (senderName == "RadioButtionDark") { styleJsonUri = new Uri(SampleHelper.Get("thinkgeo-world-streets-dark.json"), UriKind.Relative); } else if (senderName == "RadioButtionMuteblue") { styleJsonUri = new Uri(SampleHelper.Get("mutedblue.json"), UriKind.Relative); } layerOverlay.Layers.Clear(); thinkGeoMBTilesFeatureLayer = new ThinkGeoMBTilesLayer(SampleHelper.Get("tiles_Frisco.mbtiles"), styleJsonUri); UpdateTileCache(CheckBoxDisableRasterCache.IsChecked.Value); layerOverlay.Layers.Add(thinkGeoMBTilesFeatureLayer); Map.Refresh(); } }
private ImageSource GenerateMapImage() { Collection <Layer> layersToDraw = new Collection <Layer>(); // Create the background world maps using vector tiles stored locally in our MBTiles file and also set the styling though a json file ThinkGeoMBTilesLayer mbTilesLayer = new ThinkGeoMBTilesLayer(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/Mbtiles/Frisco.mbtiles"), new Uri(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/Json/thinkgeo-world-streets-light.json"), UriKind.Relative)); mbTilesLayer.Open(); layersToDraw.Add(mbTilesLayer); // Create the new layer and set the projection as the data is in srid 2276 and our background is srid 3857 (spherical mercator). ShapeFileFeatureLayer zoningLayer = new ShapeFileFeatureLayer(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/Shapefile/Zoning.shp")); zoningLayer.FeatureSource.ProjectionConverter = new ProjectionConverter(2276, 3857); zoningLayer.Open(); // Create an Area style on zoom level 1 and then apply it to all zoom levels up to 20. zoningLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = new AreaStyle(new GeoPen(GeoBrushes.Blue)); zoningLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; layersToDraw.Add(zoningLayer); // Create a GeoCanvas to do the drawing GeoCanvas canvas = GeoCanvas.CreateDefaultGeoCanvas(); // Create a GeoImage as the image to draw on GeoImage geoImage = new GeoImage(800, 600); // Start the drawing by specifying the image, extent and map units canvas.BeginDrawing(geoImage, MapUtil.GetDrawingExtent(zoningLayer.GetBoundingBox(), 800, 600), GeographyUnit.Meter); // This collection is used during drawing to pass labels in between layers so we can track collisions Collection <SimpleCandidate> labels = new Collection <SimpleCandidate>(); // Loop through all the layers and draw them to the GeoCanvas // The flush is to compact styles that use different drawing levels foreach (var layer in layersToDraw) { layer.Draw(canvas, labels); canvas.Flush(); } // End drawing, we can now use the GeoImage canvas.EndDrawing(); // Create a memory stream and save the GeoImage as a standard PNG formatted image MemoryStream imageStream = new MemoryStream(); geoImage.Save(imageStream, GeoImageFormat.Png); // Reset the image stream back to the beginning imageStream.Position = 0; return(ImageSource.FromStream(() => { return imageStream; })); }
public DisplayThinkGeoMBTilesMaps() { layerOverlay = new LayerOverlay(); var styleJsonUri = new Uri(SampleHelper.Get("thinkgeo-world-streets-light.json"), UriKind.Relative); thinkGeoMBTilesFeatureLayer = new ThinkGeoMBTilesLayer(SampleHelper.Get("tiles_Frisco.mbtiles"), styleJsonUri); tmpBitmapTileCache = null; InitializeComponent(); }
private void btnReload_Click(object sender, EventArgs e) { File.WriteAllText("tmpRenderer.json", tbxJson.Text); ThinkGeoMBTilesLayer mbTileslayer = (ThinkGeoMBTilesLayer)((LayerOverlay)mapView1.Overlays["mbtilesOverlay"]).Layers[0]; mbTileslayer.StyleJsonUri = new Uri(@"./tmpRenderer.json", UriKind.Relative); mbTileslayer.LoadStyleJson(); mapView1.Overlays["mbtilesOverlay"].Refresh(); }
private void Window_Loaded(object sender, RoutedEventArgs e) { this.wpfMap.MapUnit = GeographyUnit.Meter; ThinkGeoMBTilesLayer thinkGeoMBTilesFeatureLayer = new ThinkGeoMBTilesLayer(mbtilesPathFilename, new Uri(defaultJsonFilePath, UriKind.Relative)); layerOverlay = new LayerOverlay(); layerOverlay.Layers.Add(thinkGeoMBTilesFeatureLayer); this.wpfMap.Overlays.Add(layerOverlay); this.wpfMap.CurrentExtent = new RectangleShape(-8241733.850165642, 4972227.169416549, -8232561.406822379, 4967366.252176043); this.wpfMap.TrackOverlay.TrackEnded += TrackOverlay_TrackEnded; }
private void TrackOverlay_TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e) { InMemoryFeatureLayer trackShapeLayer = wpfMap.TrackOverlay.TrackShapeLayer; string localFilePath; SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "MB Tiles Database(*.mbtiles)|*.mbtiles"; if (saveFileDialog.ShowDialog().Value) { localFilePath = saveFileDialog.FileName.ToString(); if (File.Exists(localFilePath)) { File.Delete(localFilePath); } PolygonShape extractingPolygon = new PolygonShape(trackShapeLayer.InternalFeatures.First().GetWellKnownBinary()); wpfMap.TrackOverlay.TrackMode = TrackMode.None; pbExtractProgress.Visibility = Visibility.Visible; pbExtractProgress.IsEnabled = true; Task.Factory.StartNew(() => { ExtractTiles(extractingPolygon, localFilePath); Dispatcher.Invoke(() => { pbExtractProgress.IsEnabled = false; pbExtractProgress.Visibility = Visibility.Hidden; trackShapeLayer.InternalFeatures.Clear(); wpfMap.Refresh(wpfMap.TrackOverlay); wpfMap.TrackOverlay.TrackMode = TrackMode.Rectangle; ThinkGeoMBTilesLayer thinkGeoMBTilesFeatureLayer = new ThinkGeoMBTilesLayer(localFilePath, new Uri(defaultJsonFilePath, UriKind.Relative)); thinkGeoMBTilesFeatureLayer.BitmapTileCache = null; layerOverlay.Layers.Clear(); layerOverlay.Layers.Add(thinkGeoMBTilesFeatureLayer); chkExtractingData.IsChecked = false; wpfMap.Refresh(layerOverlay); }); }); } else { trackShapeLayer.InternalFeatures.Clear(); } }
private void btnDisplay_Click(object sender, EventArgs e) { ShapeFileFeatureLayer shapeFileFeatureLayer = new ShapeFileFeatureLayer(txtInputShapeFile.Text); shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyle.CreateSimpleAreaStyle(GeoColors.LightYellow, GeoColors.Black); shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = LineStyle.CreateSimpleLineStyle(GeoColors.Black, 2, true); shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyle.CreateSimpleCircleStyle(GeoColors.Transparent, 7, GeoColors.Black); shapeFileFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; shapeFileFeatureLayer.Open(); if (shapeFileFeatureLayer.Projection != null) { shapeFileFeatureLayer.FeatureSource.ProjectionConverter = new ProjectionConverter(shapeFileFeatureLayer.Projection.ProjString, 3857); shapeFileFeatureLayer.FeatureSource.ProjectionConverter.Open(); } LayerOverlay shapeFileOverlay = (LayerOverlay)(mapView1.Overlays["shapeFileOverlay"]); shapeFileOverlay.TileBuffer = 0; shapeFileOverlay.Layers.Add(shapeFileFeatureLayer); ThinkGeoMBTilesLayer thinkGeoMBTilesLayer = new ThinkGeoMBTilesLayer(txtMbtilesFilePathname.Text, new Uri(@"./SimpleRenderer.json", UriKind.Relative)); LayerOverlay mbtilesOverlay = (LayerOverlay)(mapView1.Overlays["mbtilesOverlay"]); mbtilesOverlay.TileBuffer = 0; mbtilesOverlay.Layers.Add(thinkGeoMBTilesLayer); mapView1.MapUnit = GeographyUnit.Meter; shapeFileFeatureLayer.Open(); mapView1.CurrentExtent = shapeFileFeatureLayer.GetBoundingBox(); mapView1.Refresh(); ckbDisplayShapeFile.Enabled = true; ckbDisplayMbtiles.Enabled = true; string jsonFile = File.ReadAllText(@".\SimpleRenderer.json"); tbxJson.Text = jsonFile; }
private void Form_Load(object sender, EventArgs e) { // It is important to set the map unit first to either feet, meters or decimal degrees. mapView.MapUnit = GeographyUnit.Meter; // Create a new overlay that will hold our new layer LayerOverlay layerOverlay = new LayerOverlay(); // Create the background world maps using vector tiles stored locally in our MBTiles file and also set the styling though a json file ThinkGeoMBTilesLayer mbTilesLayer = new ThinkGeoMBTilesLayer(@"../../../Data/Mbtiles/Frisco.mbtiles", new Uri(@"../../../Data/Json/thinkgeo-world-streets-dark.json", UriKind.Relative)); layerOverlay.Layers.Add(mbTilesLayer); // Add the overlay to the map mapView.Overlays.Add(layerOverlay); // Set the current extent of the map to an area in the data mapView.CurrentExtent = new RectangleShape(-10785086.173498387, 3913489.693302595, -10779919.030415015, 3910065.3144544438); // Refresh the map. mapView.Refresh(); }
/// <summary> /// Add the ThinkGeoMBTiles Layer to the map and load the data /// </summary> protected override void OnAppearing() { base.OnAppearing(); // It is important to set the map unit first to either feet, meters or decimal degrees. mapView.MapUnit = GeographyUnit.Meter; // Create a new overlay that will hold our new layer LayerOverlay layerOverlay = new LayerOverlay(); // Create the background world maps using vector tiles stored locally in our MBTiles file and also set the styling though a json file ThinkGeoMBTilesLayer mbTilesLayer = new ThinkGeoMBTilesLayer(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/Mbtiles/Frisco.mbtiles"), new Uri(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Data/Json/thinkgeo-world-streets-dark.json"), UriKind.Relative)); layerOverlay.Layers.Add(mbTilesLayer); // Add the overlay to the map mapView.Overlays.Add(layerOverlay); // Set the current extent of the map to an area in the data mapView.CurrentExtent = new RectangleShape(-10785086.173498387, 3913489.693302595, -10779919.030415015, 3910065.3144544438); // Refresh the map. mapView.Refresh(); }
private void TrackOverlay_TrackEnded(object sender, TrackEndedTrackInteractiveOverlayEventArgs e) { InMemoryFeatureLayer trackShapeLayer = Map1.TrackOverlay.TrackShapeLayer; string localFilePath; SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "MB Tiles Database(*.mbtiles)|*.mbtiles"; if (saveFileDialog.ShowDialog() == DialogResult.OK) { localFilePath = saveFileDialog.FileName.ToString(); if (File.Exists(localFilePath)) { File.Delete(localFilePath); } PolygonShape extractingPolygon = new PolygonShape(trackShapeLayer.InternalFeatures.First().GetWellKnownBinary()); Map1.TrackOverlay.TrackMode = TrackMode.None; ExtractTiles(extractingPolygon, localFilePath); trackShapeLayer.InternalFeatures.Clear(); Map1.Refresh(Map1.TrackOverlay); Map1.TrackOverlay.TrackMode = TrackMode.Rectangle; ThinkGeoMBTilesLayer thinkGeoMBTilesFeatureLayer = new ThinkGeoMBTilesLayer(localFilePath, new Uri(defaultJsonFilePath, UriKind.Relative)); thinkGeoMBTilesFeatureLayer.BitmapTileCache = null; layerOverlay.Layers.Clear(); layerOverlay.Layers.Add(thinkGeoMBTilesFeatureLayer); chkExtractingData.Checked = false; Map1.Refresh(layerOverlay); } else { trackShapeLayer.InternalFeatures.Clear(); } }
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; } } }
private async static Task Process(ShapeFileFeatureLayer shapeFile, string targetMbtiles, CancellationToken cancellationToken, int minZoom, int maxZoom, int tileSize, List <string> includedAttributes = null) { Console.Out.WriteLine("Processing tiles. StartZoom:{0}, EndZoom:{1}", minZoom, maxZoom); RectangleShape shapeFileBounds = shapeFile.GetBoundingBox(); shapeFile.Close(); ThinkGeoMBTilesLayer.CreateDatabase(targetMbtiles); var targetDBConnection = new SqliteConnection($"Data Source={targetMbtiles}"); targetDBConnection.Open(); // Meta Table var targetMetadata = new MetadataTable(targetDBConnection); PointShape centerPoint = shapeFileBounds.GetCenterPoint(); string center = $"{centerPoint.X},{centerPoint.Y},{maxZoom}"; string bounds = $"{shapeFileBounds.UpperLeftPoint.X},{shapeFileBounds.UpperLeftPoint.Y},{shapeFileBounds.LowerRightPoint.X},{shapeFileBounds.LowerRightPoint.Y}"; List <MetadataEntry> Entries = new List <MetadataEntry>(); Entries.Add(new MetadataEntry() { Name = "name", Value = "ThinkGeo World Streets" }); Entries.Add(new MetadataEntry() { Name = "format", Value = "pbf" }); Entries.Add(new MetadataEntry() { Name = "bounds", Value = bounds }); //"-96.85310250357627,33.10809235525063,-96.85260897712004,33.107616047247156" Entries.Add(new MetadataEntry() { Name = "center", Value = center }); // "-96.85285574034816,33.1078542012489,14" Entries.Add(new MetadataEntry() { Name = "minzoom", Value = $"{minZoom}" }); Entries.Add(new MetadataEntry() { Name = "maxzoom", Value = $"{maxZoom}" }); Entries.Add(new MetadataEntry() { Name = "attribution", Value = "Copyright @2020 ThinkGeo LLC.All rights reserved." }); Entries.Add(new MetadataEntry() { Name = "description", Value = "ThinkGeo World Street Vector Tile Data in EPSG:3857" }); Entries.Add(new MetadataEntry() { Name = "version", Value = "2.0" }); Entries.Add(new MetadataEntry() { Name = "json", Value = "" }); targetMetadata.Insert(Entries); // Tile Table var targetMap = new TilesTable(targetDBConnection); List <TilesEntry> entries = new List <TilesEntry>(); string targetFolder = Path.Combine(Path.GetDirectoryName(targetMbtiles), Path.GetFileNameWithoutExtension(targetMbtiles), "-tmp"); if (!Directory.Exists(targetFolder)) { Directory.CreateDirectory(targetFolder); } SphericalMercatorZoomLevelSet zoomLevelSet = new SphericalMercatorZoomLevelSet(); double currentScale = GetZoomLevelIndex(zoomLevelSet, minZoom); var tileMatrix = TileMatrix.GetDefaultMatrix(currentScale, tileSize, tileSize, GeographyUnit.Meter); var tileRange = tileMatrix.GetIntersectingRowColumnRange(shapeFileBounds); List <Task> tasks = new List <Task>(); for (long tileY = tileRange.MinRowIndex; tileY <= tileRange.MaxRowIndex && !cancellationToken.IsCancellationRequested; ++tileY) { for (long tileX = tileRange.MinColumnIndex; tileX <= tileRange.MaxColumnIndex && !cancellationToken.IsCancellationRequested; ++tileX) { Task task = ProcessTileRecursive(shapeFile, (int)tileY, (int)tileX, minZoom, maxZoom, cancellationToken, targetFolder, includedAttributes); tasks.Add(task); } } foreach (var task in tasks) { await task; } await Task.Run(() => { long index = 0; string[] files = Directory.GetFiles(targetFolder, "*.mvt"); foreach (string file in files) { string fileName = Path.GetFileNameWithoutExtension(file); string[] NameValues = fileName.Split('_'); byte[] bytes = File.ReadAllBytes(file); TilesEntry newEntry = new TilesEntry(); int zoomLevel = int.Parse(NameValues[0]); newEntry.ZoomLevel = zoomLevel; long row = long.Parse(NameValues[1]); row = (long)Math.Pow(2, zoomLevel) - row - 1; newEntry.TileRow = row; newEntry.TileColumn = long.Parse(NameValues[2]); newEntry.TileId = index++; newEntry.TileData = bytes; File.Delete(file); entries.Add(newEntry); if (index % 1000 == 0) { targetMap.Insert(entries); entries.Clear(); continue; } } targetMap.Insert(entries); }); targetDBConnection.Close(); }