Esempio n. 1
0
        private Matrix <double> GetPictureDrawMatrix(SKPicture picture, Position gpsPosition, Size pixelSize)
        {
            Size            platformPixelsSize = pixelSize * PlatformPixelScale;
            Matrix <double> matrix             = Matrix <double> .Build.DenseIdentity(3, 3);

            Point     mercatorPosition = gpsPosition.ToMercator();
            SKRect    sourceRect       = picture.CullRect;
            SKMapSpan drawSpan         = PixelsToMapSpanAtScale(platformPixelsSize, gpsPosition, _ScaleFactor);
            double    xScale           = platformPixelsSize.Width / sourceRect.Width;
            double    yScale           = platformPixelsSize.Height / sourceRect.Height;
            SKPoint   canvasPoint;

            if (drawSpan.Crosses180thMeridianRight() && _MercatorRenderArea.Left < SKMapExtensions.MercatorCenterOffset)
            {
                // We cross the 180th meridian to the right and are drawing to a tile on the left side of the map, so wrap around
                mercatorPosition.X -= SKMapExtensions.MercatorMapSize;
            }

            if (drawSpan.Crosses180thMeridianLeft() && _MercatorRenderArea.Right > SKMapExtensions.MercatorCenterOffset)
            {
                // We cross the 180th meridian to the right and are drawing to a tile on the left side of the map, so wrap around
                mercatorPosition.X += SKMapExtensions.MercatorMapSize;
            }

            canvasPoint = ApplyMatrix(mercatorPosition);

            matrix *= Matrix <double> .Build.Translation(canvasPoint.X, canvasPoint.Y);

            matrix *= Matrix <double> .Build.Scale(xScale, yScale);

            matrix *= Matrix <double> .Build.Translation(sourceRect.Width * -0.5, sourceRect.Height * -0.5);

            return(matrix);
        }
Esempio n. 2
0
        private async Task HandleGroundOverlayForTile(TileInfo tileInfo)
        {
            if (SharedOverlay.IsVisible)
            {
                int       virtualTileSize = Extensions.SKMapExtensions.MercatorMapSize >> tileInfo.Zoom;
                int       xPixelsStart    = tileInfo.X * virtualTileSize;
                int       yPixelsStart    = tileInfo.Y * virtualTileSize;
                double    zoomScale       = SKMapCanvas.MapTileSize / (double)virtualTileSize;
                Rectangle mercatorSpan    = new Rectangle(xPixelsStart, yPixelsStart, virtualTileSize, virtualTileSize);
                SKMapSpan tileSpan        = mercatorSpan.ToGps();

                if (tileSpan.FastIntersects(SharedOverlay.GpsBounds))
                {
                    SKBitmap         bitmap                  = DrawTileToBitmap(tileSpan, zoomScale);
                    BitmapDescriptor bitmapDescriptor        = BitmapDescriptorFactory.FromBitmap(bitmap.ToBitmap());
                    TaskCompletionSource <object> drawingTcs = new TaskCompletionSource <object>();

                    Console.WriteLine($"Refreshing ground tile at ({tileInfo.X}, {tileInfo.Y}) for zoom level {tileInfo.Zoom} ({zoomScale}) with GPS bounds {tileSpan}");

                    Device.BeginInvokeOnMainThread(() =>
                    {
                        GroundOverlay overlay;

                        lock (_GroundOverlays)
                        {
                            overlay = _GroundOverlays.FirstOrDefault(o => (o.Tag as TileInfo)?.Equals(tileInfo) ?? false);
                        }

                        if (overlay == null)
                        {
                            GroundOverlayOptions overlayOptions = new GroundOverlayOptions().PositionFromBounds(tileSpan.ToLatLng())
                                                                  .InvokeImage(bitmapDescriptor);

                            overlay     = _NativeMap.AddGroundOverlay(overlayOptions);
                            overlay.Tag = tileInfo;

                            lock (_GroundOverlays)
                            {
                                _GroundOverlays.Add(overlay);
                            }
                        }
                        else if ((overlay.Tag as TileInfo)?.NeedsRedraw ?? false)
                        {
                            overlay.SetImage(bitmapDescriptor);
                        }

                        drawingTcs.TrySetResult(null);
                    });

                    await drawingTcs.Task.ConfigureAwait(false);

                    ReleaseOverlayBitmap(bitmap);
                }
                else
                {
                    Console.WriteLine($"Ground tile at ({tileInfo.X}, {tileInfo.Y}) for zoom level {tileInfo.Zoom} already exists");
                }
            }
        }
Esempio n. 3
0
        private SKBitmap DrawTileToBitmap(SKMapSpan tileSpan, double zoomScale)
        {
            Rectangle   mercatorSpan = tileSpan.ToMercator();
            SKBitmap    bitmap       = GetOverlayBitmap();
            SKMapCanvas mapCanvas    = new SKMapCanvas(bitmap, mercatorSpan, zoomScale);

            SharedOverlay.DrawOnMap(mapCanvas, tileSpan, zoomScale);
            return(bitmap);
        }
Esempio n. 4
0
        public static SKMapSpan WrapIfRequired(this SKMapSpan self)
        {
            SKMapSpan result = self;

            if (self.Crosses180thMeridian())
            {
                // If we cross the 180th meridian, our map span is the full world width
                result = new SKMapSpan(new Position(result.Center.Latitude, 0), result.LatitudeDegrees, MaxLongitude);
            }

            return(result);
        }
Esempio n. 5
0
        public static Rectangle ToMercator(this SKMapSpan gpsSpan)
        {
            SKMapPosition topLeftGps        = gpsSpan.TopLeft;
            SKMapPosition bottomRightGps    = gpsSpan.BottomRight;
            Point         canvasTopLeft     = topLeftGps.ToMercator();
            Point         canvasBottomRight = bottomRightGps.ToMercator();

            return(new Rectangle(canvasTopLeft.X,
                                 canvasTopLeft.Y,
                                 canvasBottomRight.X - canvasTopLeft.X,
                                 canvasBottomRight.Y - canvasTopLeft.Y));
        }
Esempio n. 6
0
        public override void DrawMapRect(MKMapRect mapRect, nfloat zoomScale, CGContext context)
        {
            SKMapSpan rectSpan = mapRect.ToMapSpan();

            if (_SharedOverlay.IsVisible && rectSpan.FastIntersects(_SharedOverlay.GpsBounds))
            {
                CGRect      coreDrawRect = RectForMapRect(mapRect);
                SKBitmap    drawBitmap   = GetOverlayBitmap();
                SKMapCanvas mapCanvas    = new SKMapCanvas(drawBitmap, mapRect.ToRectangle(), zoomScale, true);

                _SharedOverlay.DrawOnMap(mapCanvas, rectSpan, zoomScale);

                Console.WriteLine($"Drawing tile for zoom scale {zoomScale} with GPS bounds {mapRect} and Mercator {mapRect.ToRectangle()}");

                context.DrawImage(coreDrawRect, drawBitmap.ToCGImage());

                // Let's exit this method so MapKit renders to screen while we free our resources in the background.
                Task.Run(() => ReleaseOverlayBitmap(drawBitmap));
            }
        }
Esempio n. 7
0
        public override void DrawOnMap(SKMapCanvas canvas, SKMapSpan canvasMapRect, double zoomScale)
        {
            SKPaint paint = new SKPaint();

            paint.IsAntialias = true;
            paint.StrokeWidth = 1;
            paint.Color       = Color.Fuchsia.ToSKColor();

            MvxLog.Instance.Log(MvxLogLevel.Trace,
                                () => $"Drawing line with coords \n" +
                                $"[{GpsBounds.Center.Longitude - GpsBounds.LongitudeDegrees - canvasMapRect.LongitudeDegrees}, " +
                                $"{GpsBounds.Center.Latitude - GpsBounds.LatitudeDegrees - canvasMapRect.LatitudeDegrees}; \n" +
                                $" {GpsBounds.Center.Longitude + GpsBounds.LongitudeDegrees}, " +
                                $"{GpsBounds.Center.Latitude + GpsBounds.LatitudeDegrees}]");

            canvas.DrawLine(GpsBounds.Center.Latitude + GpsBounds.LatitudeDegrees - canvasMapRect.LatitudeDegrees,
                            GpsBounds.Center.Longitude + GpsBounds.LongitudeDegrees - canvasMapRect.LongitudeDegrees,
                            GpsBounds.Center.Latitude + GpsBounds.LatitudeDegrees,
                            GpsBounds.Center.Longitude + GpsBounds.LongitudeDegrees,
                            paint);
        }
Esempio n. 8
0
        public override void DrawOnMap(SKMapCanvas canvas, SKMapSpan canvasMapRect, double zoomScale)
        {
            SKPaint paint = new SKPaint();

            paint.IsAntialias = true;
            paint.StrokeWidth = 1;
            paint.Color       = Color.Fuchsia.ToSKColor();

            if (canvasMapRect.Center.Latitude > 0)
            {
                canvas.DrawLine(new Position(canvasMapRect.Center.Latitude + canvasMapRect.LatitudeDegrees, canvasMapRect.Center.Longitude),
                                new Position(canvasMapRect.Center.Latitude - canvasMapRect.LatitudeDegrees,
                                             canvasMapRect.Center.Longitude + canvasMapRect.LongitudeDegrees),
                                paint);
                canvas.DrawLine(new Position(canvasMapRect.Center.Latitude - canvasMapRect.LatitudeDegrees,
                                             canvasMapRect.Center.Longitude + canvasMapRect.LongitudeDegrees),
                                new Position(canvasMapRect.Center.Latitude - canvasMapRect.LatitudeDegrees,
                                             canvasMapRect.Center.Longitude - canvasMapRect.LongitudeDegrees),
                                paint);
                canvas.DrawLine(new Position(canvasMapRect.Center.Latitude - canvasMapRect.LatitudeDegrees,
                                             canvasMapRect.Center.Longitude - canvasMapRect.LongitudeDegrees),
                                new Position(canvasMapRect.Center.Latitude + canvasMapRect.LatitudeDegrees, canvasMapRect.Center.Longitude),
                                paint);
            }
            else
            {
                canvas.DrawLine(new Position(canvasMapRect.Center.Latitude - canvasMapRect.LatitudeDegrees, canvasMapRect.Center.Longitude),
                                new Position(canvasMapRect.Center.Latitude + canvasMapRect.LatitudeDegrees,
                                             canvasMapRect.Center.Longitude + canvasMapRect.LongitudeDegrees),
                                paint);
                canvas.DrawLine(new Position(canvasMapRect.Center.Latitude + canvasMapRect.LatitudeDegrees,
                                             canvasMapRect.Center.Longitude + canvasMapRect.LongitudeDegrees),
                                new Position(canvasMapRect.Center.Latitude + canvasMapRect.LatitudeDegrees,
                                             canvasMapRect.Center.Longitude - canvasMapRect.LongitudeDegrees),
                                paint);
                canvas.DrawLine(new Position(canvasMapRect.Center.Latitude + canvasMapRect.LatitudeDegrees,
                                             canvasMapRect.Center.Longitude - canvasMapRect.LongitudeDegrees),
                                new Position(canvasMapRect.Center.Latitude - canvasMapRect.LatitudeDegrees, canvasMapRect.Center.Longitude),
                                paint);
            }

            paint.Style       = SKPaintStyle.Stroke;
            paint.StrokeWidth = 10;
            paint.StrokeCap   = SKStrokeCap.Round;
            paint.StrokeJoin  = SKStrokeJoin.Round;
            paint.Color       = Color.Red.ToSKColor();
            SKMapPath zonePath = canvas.CreateEmptyMapPath();

            zonePath.MoveTo((float)(baseBounds.Center.Latitude - baseBounds.LatitudeDegrees), (float)baseBounds.Center.Longitude);
            zonePath.LineTo((float)(baseBounds.Center.Latitude + baseBounds.LatitudeDegrees), (float)(baseBounds.Center.Longitude + baseBounds.LongitudeDegrees));
            zonePath.LineTo((float)(baseBounds.Center.Latitude + baseBounds.LatitudeDegrees), (float)(baseBounds.Center.Longitude - baseBounds.LongitudeDegrees));
            zonePath.Close();

            canvas.DrawPath(zonePath, paint);

            paint.Color = Color.Green.MultiplyAlpha(0.5).ToSKColor();
            Size    currentScaleStrokeArea = SKMapCanvas.PixelsToMapSizeAtScale(new Size(5, 5), baseBounds.Center, zoomScale);
            MapSpan insetBounds            = new MapSpan(baseBounds.Center,
                                                         baseBounds.LatitudeDegrees - currentScaleStrokeArea.Height,
                                                         baseBounds.LongitudeDegrees - currentScaleStrokeArea.Width);

            canvas.DrawRect(insetBounds, paint);

            paint.StrokeWidth = 1;
            paint.Color       = Color.Black.ToSKColor();
            canvas.DrawRect(baseBounds, paint);

            paint.Color = Color.Black.ToSKColor();
            canvas.DrawRect(GpsBounds, paint);

            IResourceLocator resLocator = Mvx.IoCProvider.Resolve <IResourceLocator>();
            string           resPath    = resLocator.GetResourcePath(ResourceKeys.ImagesKey, "symbol_logo.svg");
            SKSvg            logoSvg    = new SKSvg();

            logoSvg.Load(resLocator.ResourcesAssembly.GetManifestResourceStream(resPath));
            canvas.DrawPicture(logoSvg.Picture, baseBounds.Center, new Size(100, 100));
        }
Esempio n. 9
0
 public static bool Crosses180thMeridianLeft(this SKMapSpan self)
 {
     return(self.Center.Longitude - self.LongitudeDegrees < MinLongitude);
 }
Esempio n. 10
0
 public static bool Crosses180thMeridianRight(this SKMapSpan self)
 {
     return(self.Center.Longitude + self.LongitudeDegrees > MaxLongitude);
 }
Esempio n. 11
0
 public static bool Crosses180thMeridian(this SKMapSpan self)
 {
     return(self.Crosses180thMeridianRight() ||
            self.Crosses180thMeridianLeft());
 }
Esempio n. 12
0
        public override void DrawOnMap(SKMapCanvas canvas, SKMapSpan canvasMapRect, double zoomScale)
        {
            SKPaint paint = new SKPaint();

            paint.IsAntialias = true;
            paint.StrokeWidth = 1;
            paint.Color       = Color.Fuchsia.ToSKColor();

            if (canvasMapRect.Center.Latitude > 0)
            {
                canvas.DrawLine(canvasMapRect.Center.Latitude - canvasMapRect.LatitudeDegrees,
                                canvasMapRect.Center.Longitude - canvasMapRect.LongitudeDegrees,
                                canvasMapRect.Center.Latitude + canvasMapRect.LatitudeDegrees,
                                canvasMapRect.Center.Longitude + canvasMapRect.LongitudeDegrees,
                                paint);
            }
            else
            {
                canvas.DrawLine(canvasMapRect.Center.Latitude + canvasMapRect.LatitudeDegrees,
                                canvasMapRect.Center.Longitude - canvasMapRect.LongitudeDegrees,
                                canvasMapRect.Center.Latitude - canvasMapRect.LatitudeDegrees,
                                canvasMapRect.Center.Longitude + canvasMapRect.LongitudeDegrees,
                                paint);
            }

            paint.StrokeWidth = 5;
            paint.Color       = Color.Blue.ToSKColor();

            canvas.DrawLine(baseBounds.Center.Latitude + baseBounds.LatitudeDegrees,
                            baseBounds.Center.Longitude + baseBounds.LongitudeDegrees,
                            baseBounds.Center.Latitude - baseBounds.LatitudeDegrees,
                            baseBounds.Center.Longitude - baseBounds.LongitudeDegrees,
                            paint);

            canvas.DrawLine(baseBounds.Center.Latitude - baseBounds.LatitudeDegrees,
                            baseBounds.Center.Longitude + baseBounds.LongitudeDegrees,
                            baseBounds.Center.Latitude + baseBounds.LatitudeDegrees,
                            baseBounds.Center.Longitude - baseBounds.LongitudeDegrees,
                            paint);

            paint.Color = Color.Red.ToSKColor();

            canvas.DrawLine(baseBounds.Center.Latitude + baseBounds.LatitudeDegrees,
                            baseBounds.Center.Longitude + baseBounds.LongitudeDegrees,
                            baseBounds.Center.Latitude - baseBounds.LatitudeDegrees,
                            baseBounds.Center.Longitude - baseBounds.LongitudeDegrees,
                            paint,
                            false);

            canvas.DrawLine(baseBounds.Center.Latitude - baseBounds.LatitudeDegrees,
                            baseBounds.Center.Longitude + baseBounds.LongitudeDegrees,
                            baseBounds.Center.Latitude + baseBounds.LatitudeDegrees,
                            baseBounds.Center.Longitude - baseBounds.LongitudeDegrees,
                            paint,
                            false);
            paint.StrokeWidth = 5;
            paint.Color       = Color.Orange.ToSKColor();

            canvas.DrawLine(GpsBounds.Center.Latitude + GpsBounds.LatitudeDegrees,
                            GpsBounds.Center.Longitude - GpsBounds.LongitudeDegrees,
                            GpsBounds.Center.Latitude - GpsBounds.LatitudeDegrees,
                            GpsBounds.Center.Longitude + GpsBounds.LongitudeDegrees,
                            paint,
                            false);

            canvas.DrawLine(GpsBounds.Center.Latitude + GpsBounds.LatitudeDegrees,
                            GpsBounds.Center.Longitude + GpsBounds.LongitudeDegrees,
                            GpsBounds.Center.Latitude - GpsBounds.LatitudeDegrees,
                            GpsBounds.Center.Longitude - GpsBounds.LongitudeDegrees,
                            paint,
                            false);
        }
Esempio n. 13
0
 public TestLineMapOverlay()
 {
     baseBounds = new SKMapSpan(new Position(0, -180), 1, 1);
     GpsBounds  = MapSpanExtensions.WorldSpan;
 }
Esempio n. 14
0
        public static Size PixelsToMapSizeAtScale(Size pixelsSize, Position mapPosition, double zoomScale)
        {
            SKMapSpan gpsArea = PixelsToMapSpanAtScale(pixelsSize, mapPosition, zoomScale);

            return(new Size(gpsArea.LongitudeDegrees * 2, gpsArea.LatitudeDegrees * 2));
        }
Esempio n. 15
0
        public static LatLngBounds ToLatLng(this Rectangle self)
        {
            SKMapSpan mapSpan = self.ToGps();

            return(mapSpan.ToLatLng());
        }
Esempio n. 16
0
 public static LatLngBounds ToLatLng(this SKMapSpan self)
 {
     LatLngBounds.Builder builder = new LatLngBounds.Builder().Include(self.BottomLeft.ToLatLng())
                                    .Include(self.TopRight.ToLatLng());
     return(builder.Build());
 }