Пример #1
0
        /// <summary>
        /// Converts geographic coordinates to view x/y coordinates in the map view.
        /// </summary>
        /// <param name="in">
        ///            the geographic coordinates </param>
        /// <returns> x/y view coordinates for the given location </returns>
        public virtual Point ToPixels(LatLong @in)
        {
            if (@in == null || this.mapView.Width <= 0 || this.mapView.Height <= 0)
            {
                return(null);
            }

            MapPosition mapPosition = this.mapView.Model.mapViewPosition.MapPosition;

            // this means somehow the mapview is not yet properly set up, see issue #308.
            if (mapPosition == null)
            {
                return(null);
            }

            // calculate the pixel coordinates of the top left corner
            LatLong latLong = mapPosition.LatLong;
            long    mapSize = MercatorProjection.GetMapSize(mapPosition.ZoomLevel, this.mapView.Model.displayModel.TileSize);
            double  pixelX  = MercatorProjection.LongitudeToPixelX(latLong.Longitude, mapSize);
            double  pixelY  = MercatorProjection.LatitudeToPixelY(latLong.Latitude, mapSize);

            pixelX -= this.mapView.Width >> 1;
            pixelY -= this.mapView.Height >> 1;

            // create a new point and return it
            return(new Point((int)(MercatorProjection.LongitudeToPixelX(@in.Longitude, mapSize) - pixelX), (int)(MercatorProjection.LatitudeToPixelY(@in.Latitude, mapSize) - pixelY)));
        }
Пример #2
0
        private void AdjustFrameBufferMatrix(MapPosition mapPositionFrameBuffer, Dimension mapViewDimension, double scaleFactor, LatLong pivot)
        {
            MapPosition mapViewPosition = this.model.mapViewPosition.MapPosition;

            long mapSize = MercatorProjection.GetMapSize(mapPositionFrameBuffer.ZoomLevel, model.displayModel.TileSize);

            Point pointFrameBuffer = MercatorProjection.GetPixel(mapPositionFrameBuffer.LatLong, mapSize);
            Point pointMapPosition = MercatorProjection.GetPixel(mapViewPosition.LatLong, mapSize);

            double diffX = pointFrameBuffer.X - pointMapPosition.X;
            double diffY = pointFrameBuffer.Y - pointMapPosition.Y;
            // we need to compute the pivot distance from the map center
            // as we will need to find the pivot point for the
            // frame buffer (which generally has not the same size as the
            // map view).
            double pivotDistanceX = 0d;
            double pivotDistanceY = 0d;

            if (pivot != null)
            {
                Point pivotXY = MercatorProjection.GetPixel(pivot, mapSize);
                pivotDistanceX = pivotXY.X - pointFrameBuffer.X;
                pivotDistanceY = pivotXY.Y - pointFrameBuffer.Y;
            }

            float currentScaleFactor = (float)(scaleFactor / Math.Pow(2, mapPositionFrameBuffer.ZoomLevel));

            this.frameBuffer.AdjustMatrix((float)diffX, (float)diffY, currentScaleFactor, mapViewDimension, (float)pivotDistanceX, (float)pivotDistanceY);
        }
Пример #3
0
 /// <summary>
 /// Sets the new center position and zoom level of the map.
 /// </summary>
 public virtual void SetMapPosition(MapPosition mapPosition, bool animated)
 {
     lock (this)
     {
         setCenterInternal(mapPosition.LatLong.Latitude, mapPosition.LatLong.Longitude);
         setZoomLevelInternal(mapPosition.ZoomLevel, animated);
     }
     NotifyObservers();
 }
Пример #4
0
 public virtual void FrameFinished(MapPosition frameMapPosition)
 {
     lock (this)
     {
         // swap both bitmap references
         IBitmap bitmapTemp = this.bitmap1;
         this.bitmap1 = this.bitmap2;
         this.bitmap2 = bitmapTemp;
     }
     // taking this out of the synchronized region removes a deadlock potential
     // at the small risk of an inconsistent zoom
     this.frameBufferModel.MapPosition = frameMapPosition;
 }
Пример #5
0
        public static Point GetTopLeftPoint(MapPosition mapPosition, Dimension canvasDimension, int tileSize)
        {
            LatLong centerPoint = mapPosition.LatLong;

            int halfCanvasWidth  = canvasDimension.Width / 2;
            int halfCanvasHeight = canvasDimension.Height / 2;

            long   mapSize = MercatorProjection.GetMapSize(mapPosition.ZoomLevel, tileSize);
            double pixelX  = Math.Round(MercatorProjection.LongitudeToPixelX(centerPoint.Longitude, mapSize));
            double pixelY  = Math.Round(MercatorProjection.LatitudeToPixelY(centerPoint.Latitude, mapSize));

            return(new Point((int)pixelX - halfCanvasWidth, (int)pixelY - halfCanvasHeight));
        }
Пример #6
0
        protected internal override void DoWork()
        {
            long startTime = System.DateTime.Now.Ticks;

            this.redrawNeeded = false;

            FrameBuffer frameBuffer = this.mapView.FrameBuffer;
            IBitmap     bitmap      = frameBuffer.DrawingBitmap;

            if (bitmap != null)
            {
                this.drawingCanvas.Bitmap = bitmap;

                MapPosition mapPosition     = this.mapViewPosition.MapPosition;
                Dimension   canvasDimension = this.drawingCanvas.Dimension;
                int         tileSize        = this.mapView.Model.displayModel.TileSize;
                BoundingBox boundingBox     = MapPositionUtil.GetBoundingBox(mapPosition, canvasDimension, tileSize);
                Point       topLeftPoint    = MapPositionUtil.GetTopLeftPoint(mapPosition, canvasDimension, tileSize);

                foreach (Layer layer in this.layers)
                {
                    if (layer.Visible)
                    {
                        layer.Draw(boundingBox, mapPosition.ZoomLevel, this.drawingCanvas, topLeftPoint);
                    }
                }

                if (!mapViewPosition.AnimationInProgress())
                {
                    // this causes a lot of flickering when an animation
                    // is in progress
                    frameBuffer.FrameFinished(mapPosition);
                    this.mapView.Repaint();
                }
                else
                {
                    // make sure that we redraw at the end
                    this.redrawNeeded = true;
                }
            }

            long elapsedMilliseconds = (System.DateTime.Now.Ticks - startTime) / 10000;
            long timeSleep           = MILLISECONDS_PER_FRAME - elapsedMilliseconds;

            if (timeSleep > 1 && !Interrupted)
            {
                System.Threading.Tasks.Task.Delay((int)timeSleep);
            }
        }
Пример #7
0
        public static BoundingBox GetBoundingBox(MapPosition mapPosition, Dimension canvasDimension, int tileSize)
        {
            long   mapSize = MercatorProjection.GetMapSize(mapPosition.ZoomLevel, tileSize);
            double pixelX  = MercatorProjection.LongitudeToPixelX(mapPosition.LatLong.Longitude, mapSize);
            double pixelY  = MercatorProjection.LatitudeToPixelY(mapPosition.LatLong.Latitude, mapSize);

            int halfCanvasWidth  = canvasDimension.Width / 2;
            int halfCanvasHeight = canvasDimension.Height / 2;

            double pixelXMin = Math.Max(0, pixelX - halfCanvasWidth);
            double pixelYMin = Math.Max(0, pixelY - halfCanvasHeight);
            double pixelXMax = Math.Min(mapSize, pixelX + halfCanvasWidth);
            double pixelYMax = Math.Min(mapSize, pixelY + halfCanvasHeight);

            double minLatitude  = MercatorProjection.PixelYToLatitude(pixelYMax, mapSize);
            double minLongitude = MercatorProjection.PixelXToLongitude(pixelXMin, mapSize);
            double maxLatitude  = MercatorProjection.PixelYToLatitude(pixelYMin, mapSize);
            double maxLongitude = MercatorProjection.PixelXToLongitude(pixelXMax, mapSize);

            return(new BoundingBox(minLatitude, minLongitude, maxLatitude, maxLongitude));
        }
Пример #8
0
        public void OnChange()
        {
            Dimension mapViewDimension = this.model.mapViewDimension.Dimension;

            if (mapViewDimension == null)
            {
                // at this point map view not visible
                return;
            }

            double overdrawFactor = this.model.frameBufferModel.OverdrawFactor;

            if (DimensionChangeNeeded(mapViewDimension, overdrawFactor))
            {
                Dimension newDimension = CalculateFrameBufferDimension(mapViewDimension, overdrawFactor);
                if (!useSquareFrameBuffer || frameBuffer.Dimension == null || newDimension.Width > frameBuffer.Dimension.Width || newDimension.Height > frameBuffer.Dimension.Height)
                {
                    // new dimensions if we either always reallocate on config change or if new dimension
                    // is larger than the old
                    this.frameBuffer.Dimension = newDimension;
                }
                this.lastMapViewDimension = mapViewDimension;
                this.lastOverdrawFactor   = overdrawFactor;
            }

            lock (this.model.mapViewPosition)
            {
                lock (this.frameBuffer)
                {
                    // we need resource ordering here to avoid deadlock
                    MapPosition mapPositionFrameBuffer = this.model.frameBufferModel.MapPosition;
                    if (mapPositionFrameBuffer != null)
                    {
                        double  scaleFactor = this.model.mapViewPosition.ScaleFactor;
                        LatLong pivot       = this.model.mapViewPosition.Pivot;
                        AdjustFrameBufferMatrix(mapPositionFrameBuffer, mapViewDimension, scaleFactor, pivot);
                    }
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Calculates the required length and value of the scalebar
        /// </summary>
        /// <param name="unitAdapter">
        ///            the DistanceUnitAdapter to calculate for </param>
        /// <returns> a <seealso cref="ScaleBarLengthAndValue"/> object containing the required scaleBarLength and scaleBarValue </returns>
        protected internal virtual ScaleBarLengthAndValue CalculateScaleBarLengthAndValue(DistanceUnitAdapter unitAdapter)
        {
            this.prevMapPosition = this.mapViewPosition.MapPosition;
            double groundResolution = MercatorProjection.CalculateGroundResolution(this.prevMapPosition.LatLong.Latitude, MercatorProjection.GetMapSize(this.prevMapPosition.ZoomLevel, this.displayModel.TileSize));

            groundResolution = groundResolution / unitAdapter.MeterRatio;
            int[] scaleBarValues = unitAdapter.ScaleBarValues;

            int scaleBarLength = 0;
            int mapScaleValue  = 0;

            for (int i = 0; i < scaleBarValues.Length; ++i)
            {
                mapScaleValue  = scaleBarValues[i];
                scaleBarLength = (int)(mapScaleValue / groundResolution);
                if (scaleBarLength < (this.mapScaleBitmap.Width - 10))
                {
                    break;
                }
            }

            return(new ScaleBarLengthAndValue(scaleBarLength, mapScaleValue));
        }
Пример #10
0
        /// <summary>
        /// Computes the geographic coordinates of a screen point.
        /// </summary>
        /// <returns> the coordinates of the x/y point </returns>
        public virtual LatLong FromPixels(double x, double y)
        {
            if (this.mapView.Width <= 0 || this.mapView.Height <= 0)
            {
                return(null);
            }

            // this uses the framebuffer position, the mapview position can be out of sync with
            // what the user sees on the screen if an animation is in progress
            MapPosition mapPosition = this.mapView.Model.frameBufferModel.MapPosition;

            // this means somehow the mapview is not yet properly set up, see issue #308.
            if (mapPosition == null)
            {
                return(null);
            }

            // calculate the pixel coordinates of the top left corner
            LatLong latLong = mapPosition.LatLong;
            long    mapSize = MercatorProjection.GetMapSize(mapPosition.ZoomLevel, this.mapView.Model.displayModel.TileSize);
            double  pixelX  = MercatorProjection.LongitudeToPixelX(latLong.Longitude, mapSize);
            double  pixelY  = MercatorProjection.LatitudeToPixelY(latLong.Latitude, mapSize);

            pixelX -= this.mapView.Width >> 1;
            pixelY -= this.mapView.Height >> 1;

            // catch outer map limits
            try
            {
                // convert the pixel coordinates to a LatLong and return it
                return(new LatLong(MercatorProjection.PixelYToLatitude(pixelY + y, mapSize), MercatorProjection.PixelXToLongitude(pixelX + x, mapSize)));
            }
            catch (Exception)
            {
                return(null);
            }
        }