示例#1
0
        /// <summary>
        /// Triggers rendering.
        /// </summary>
        public void TriggerRendering(bool force)
        {
            if (this.SurfaceWidth == 0)
            { // nothing to render yet!
                return;
            }

            // create the view that would be use for rendering.
            View2D view = _cacheRenderer.Create((int)(this.SurfaceWidth * _extra), (int)(this.SurfaceHeight * _extra),
                                                this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoom),
                                                this.MapCenter, _invertX, _invertY, this.MapTilt);

            // ... and compare to the previous rendered view.
            if (!force && _previouslyRenderedView != null &&
                view.Equals(_previouslyRenderedView))
            {
                return;
            }
            _previouslyRenderedView = view;

            // end existing rendering thread.
            if (_renderingThread != null &&
                _renderingThread.IsAlive)
            {
                if (_cacheRenderer.IsRunning)
                {
                    this.Map.ViewChangedCancel();
                    _cacheRenderer.CancelAndWait();
                }
            }

            // start new rendering thread.
            _renderingThread = new Thread(new ThreadStart(Render));
            _renderingThread.Start();
        }
示例#2
0
        /// <summary>
        /// Notifies change
        /// </summary>
        internal void TriggerRendering()
        {
            if (_rect.Width == 0)
            {
                return;
            }

            if (Monitor.TryEnter(_cacheRenderer, 1000))
            {             // entered the exclusive lock area.
                try
                {
                    // create the view that would be use for rendering.
                    float  size = System.Math.Max(_rect.Width, _rect.Height);
                    View2D view = _cacheRenderer.Create((int)(size * _extra), (int)(size * _extra),
                                                        this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoom),
                                                        this.MapCenter, _invertX, _invertY, this.MapTilt);

                    // ... and compare to the previous rendered view.
                    if (_previouslyRenderedView != null &&
                        view.Equals(_previouslyRenderedView))
                    {
                        _listener.NotifyRenderSuccess(view, this.MapZoom, 0);
                        return;
                    }
                    _previouslyRenderedView = view;

                    // end existing rendering thread.
                    if (_renderingThread != null &&
                        _renderingThread.IsAlive)
                    {
                        if (_cacheRenderer.IsRunning)
                        {
                            _cacheRenderer.CancelAndWait();
                        }
                    }

                    // start new rendering thread.
                    _renderingThread = new Thread(new ThreadStart(Render));
                    _renderingThread.Start();
                }
                finally
                {
                    Monitor.Exit(_cacheRenderer);
                }
            }
        }
示例#3
0
        /// <summary>
        /// Notifies change
        /// </summary>
        /// <param name="touch">If set to <c>true</c> change was trigger by touch.</param>
        internal void Change(bool touch)
        {
            if (_rect.Width == 0)
            {
                return;
            }

            lock (_cacheRenderer) {
                // create the view that would be use for rendering.
                View2D view = _cacheRenderer.Create((int)(_rect.Width * _extra), (int)(_rect.Height * _extra),
                                                    this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoom),
                                                    this.MapCenter, _invertX, _invertY, this.MapTilt);

                // ... and compare to the previous rendered view.
                if (_previousRenderedZoom != null &&
                    view.Equals(_previousRenderedZoom))
                {
                    return;
                }
                _previousRenderedZoom = view;

                // end existing rendering thread.
                if (_renderingThread != null &&
                    _renderingThread.IsAlive)
                {
                    if (_cacheRenderer.IsRunning)
                    {
                        _cacheRenderer.CancelAndWait();
                    }

                    _renderingThread.Abort();
                }

                // start new rendering thread.
                _renderingThread = new Thread(new ThreadStart(Render));
                _renderingThread.Start();

                // raise touched event.
                if (touch)
                {
                    this.RaiseMapTouched();
                }
            }
        }
示例#4
0
        /// <summary>
        /// Triggers rendering.
        /// </summary>
        public void TriggerRendering(bool force)
        {
            try
            {
                if (this.SurfaceWidth == 0)
                { // nothing to render yet!
                    return;
                }

                // create the view that would be use for rendering.
                View2D view = _cacheRenderer.Create((int)(this.SurfaceWidth * _extra), (int)(this.SurfaceHeight * _extra),
                                                    this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoom),
                                                    this.MapCenter, _invertX, _invertY, this.MapTilt);

                // ... and compare to the previous rendered view.
                if (!force && _previouslyRenderedView != null &&
                    view.Equals(_previouslyRenderedView))
                {
                    return;
                }
                _previouslyRenderedView = view;

                // end existing rendering thread.
                if (_renderingThread != null &&
                    _renderingThread.IsAlive)
                {
                    if (_cacheRenderer.IsRunning)
                    {
                        this.Map.ViewChangedCancel();
                        _cacheRenderer.CancelAndWait();
                    }
                }

                // start new rendering thread.
                _renderingThread = new Thread(new ThreadStart(Render));
                _renderingThread.Start();
            }
            catch (Exception ex)
            {
                OsmSharp.Logging.Log.TraceEvent("MapViewSurface", TraceEventType.Critical,
                                                string.Format("An unhandled exception occured:{0}", ex.ToString()));
            }
        }
示例#5
0
        /// <summary>
        /// Renders the current complete scene.
        /// </summary>
        private void Render()
        {
            try
            {
                if (_renderingSuspended)
                { // no rendering when rendering is suspended.
                    return;
                }

                if (_cacheRenderer.IsRunning)
                { // cancel previous render.
                    _cacheRenderer.CancelAndWait();
                }

                // make sure only on thread at the same time is using the renderer.
                lock (_cacheRenderer)
                {
                    this.Map.ViewChangedCancel();

                    // build the layers list.
                    var layers = new List <Layer>();
                    for (int layerIdx = 0; layerIdx < this.Map.LayerCount; layerIdx++)
                    { // get the layer.
                        if (this.Map[layerIdx].IsVisible)
                        {
                            layers.Add(this.Map[layerIdx]);
                        }
                    }

                    // add the internal layers.
                    layers.Add(_makerLayer);

                    if (this.SurfaceHeight == 0)
                    { // the surface has no height yet. Impossible to render like this.
                        return;
                    }

                    // get old image if available.
                    NativeImage image = null;
                    if (_offScreenBuffer != null)
                    { // get the native image from the off-screen buffer.
                        image = _offScreenBuffer.NativeImage as NativeImage;
                    }

                    // resize image if needed.
                    float sizeX = this.SurfaceWidth;
                    float sizeY = this.SurfaceHeight;
                    //if(this.MapAllowTilt)
                    //{ // when rotation is allowed make sure a square is rendered.
                    //    sizeX = System.Math.Max(this.SurfaceWidth, this.SurfaceHeight);
                    //    sizeY = System.Math.Max(this.SurfaceWidth, this.SurfaceHeight);
                    //}
                    // float size = System.Math.Max(this.SurfaceHeight, this.SurfaceWidth);
                    if (image == null ||
                        image.Image.Width != (int)(sizeX * _extra) ||
                        image.Image.Height != (int)(sizeY * _extra))
                    {     // create a bitmap and render there.
                        if (image != null)
                        { // make sure to dispose the old image.
                            image.Dispose();
                        }
                        image = new NativeImage(global::Android.Graphics.Bitmap.CreateBitmap((int)(sizeX * _extra),
                                                                                             (int)(sizeY * _extra),
                                                                                             global::Android.Graphics.Bitmap.Config.Argb8888));
                    }

                    // create and reset the canvas.
                    using (var canvas = new global::Android.Graphics.Canvas(image.Image))
                    {
                        canvas.DrawColor(new global::Android.Graphics.Color(
                                             SimpleColor.FromKnownColor(KnownColor.White).Value));

                        // create the view.
                        double[] sceneCenter     = this.Map.Projection.ToPixel(this.MapCenter.Latitude, this.MapCenter.Longitude);
                        float    mapZoom         = this.MapZoom;
                        float    sceneZoomFactor = (float)this.Map.Projection.ToZoomFactor(this.MapZoom);

                        // create the view for this control.
                        float scaledNormalWidth  = image.Image.Width / _bufferFactor;
                        float scaledNormalHeight = image.Image.Height / _bufferFactor;
                        var   view = View2D.CreateFrom((float)sceneCenter[0], (float)sceneCenter[1],
                                                       scaledNormalWidth * _extra, scaledNormalHeight * _extra, sceneZoomFactor,
                                                       _invertX, _invertY, this.MapTilt);

                        long before = DateTime.Now.Ticks;

                        OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", TraceEventType.Information,
                                                        "Rendering Start");

                        // notify the map that the view has changed.
                        if (_previouslyChangedView == null ||
                            !_previouslyChangedView.Equals(view))
                        { // report change once!
                            var normalView = View2D.CreateFrom((float)sceneCenter[0], (float)sceneCenter[1],
                                                               scaledNormalWidth, scaledNormalHeight, sceneZoomFactor,
                                                               _invertX, _invertY, this.MapTilt);
                            this.Map.ViewChanged((float)this.Map.Projection.ToZoomFactor(this.MapZoom), this.MapCenter,
                                                 normalView, view);
                            _previouslyChangedView = view;
                            long afterViewChanged = DateTime.Now.Ticks;
                            OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", TraceEventType.Information,
                                                            "View change took: {0}ms @ zoom level {1}",
                                                            (new TimeSpan(afterViewChanged - before).TotalMilliseconds), this.MapZoom);
                        }

                        // does the rendering.
                        bool complete = _cacheRenderer.Render(canvas, layers, view, (float)this.Map.Projection.ToZoomFactor(this.MapZoom));

                        long afterRendering = DateTime.Now.Ticks;
                        OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", TraceEventType.Information,
                                                        "Rendering took: {0}ms @ zoom level {1} and {2}",
                                                        (new TimeSpan(afterRendering - before).TotalMilliseconds), this.MapZoom, this.MapCenter);
                        if (complete)
                        { // there was no cancellation, the rendering completely finished.
                            // add the result to the scene cache.
                            // add the newly rendered image again.
                            if (_offScreenBuffer == null)
                            { // create the offscreen buffer first.
                                _offScreenBuffer = new ImageTilted2D(view.Rectangle, image, float.MinValue, float.MaxValue);
                            }
                            else
                            { // augment the previous buffer.
                                _offScreenBuffer.Bounds      = view.Rectangle;
                                _offScreenBuffer.NativeImage = image;
                            }

                            var temp = _onScreenBuffer;
                            _onScreenBuffer  = _offScreenBuffer;
                            _offScreenBuffer = temp;
                        }

                        long after = DateTime.Now.Ticks;

                        if (complete)
                        { // report a successful render to listener.
                            _listener.NotifyRenderSuccess(view, mapZoom, (int)new TimeSpan(after - before).TotalMilliseconds);
                        }
                    }
                }

                // notify the the current surface of the new rendering.
                this.PostInvalidate();
            }
            catch (Exception ex)
            { // exceptions can be thrown when the mapview is disposed while rendering.
                // don't worry too much about these, the mapview is garbage anyway.
                OsmSharp.Logging.Log.TraceEvent("MapViewSurface", TraceEventType.Critical,
                                                string.Format("An unhandled exception occured:{0}", ex.ToString()));
            }
        }
示例#6
0
        /// <summary>
        /// Render the current complete scene.
        /// </summary>
        void Render()
        {
            try {
                RectangleF rect = _rect;

                lock (this.Map) {
                    //lock (_cacheRenderer) { // make sure only on thread at the same time is using the renderer.
                    // create the view.
                    View2D view = _cacheRenderer.Create((int)(rect.Width * _extra), (int)(rect.Height * _extra),
                                                        this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoom),
                                                        this.MapCenter, _invertX, _invertY, this.MapTilt);

                    if (view.Equals(_previousRenderedZoom))
                    {
                        return;
                    }

                    if (rect.Width == 0)               // only render if a proper size is known.
                    {
                        return;
                    }

                    OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information,
                                                    "Before lock.");

                    long before = DateTime.Now.Ticks;
                    //				OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information,
                    //				                                "Rendering Start");

                    // build the layers list.
                    var layers = new List <ILayer> ();
                    for (int layerIdx = 0; layerIdx < this.Map.LayerCount; layerIdx++)
                    {
                        layers.Add(this.Map [layerIdx]);
                    }

                    // add the internal layer.
                    // TODO: create marker layer.
                    int imageWidth  = (int)(rect.Width * _extra * _scaleFactor);
                    int imageHeight = (int)(rect.Height * _extra * _scaleFactor);

                    // create a new bitmap context.
                    CGColorSpace space            = CGColorSpace.CreateDeviceRGB();
                    int          bytesPerPixel    = 4;
                    int          bytesPerRow      = bytesPerPixel * imageWidth;
                    int          bitsPerComponent = 8;
                    if (_bytescache == null)
                    {
                        _bytescache = new byte[bytesPerRow * imageHeight];
                    }
                    CGBitmapContext gctx = new CGBitmapContext(null, imageWidth, imageHeight,
                                                               bitsPerComponent, bytesPerRow,
                                                               space,               // kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast
                                                               CGBitmapFlags.PremultipliedFirst | CGBitmapFlags.ByteOrder32Big);

                    // notify the map that the view has changed.
                    this.Map.ViewChanged((float)this.Map.Projection.ToZoomFactor(this.MapZoom), this.MapCenter,
                                         view);
                    long afterViewChanged = DateTime.Now.Ticks;
                    OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information,
                                                    "View change took: {0}ms @ zoom level {1}",
                                                    (new TimeSpan(afterViewChanged - before).TotalMilliseconds), this.MapZoom);

                    // does the rendering.
                    bool complete = _cacheRenderer.Render(new CGContextWrapper(gctx,
                                                                               new RectangleF(0, 0, (int)(rect.Width * _extra), (int)(rect.Height * _extra))),
                                                          layers, view);

                    long afterRendering = DateTime.Now.Ticks;
                    OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information,
                                                    "Rendering took: {0}ms @ zoom level {1}",
                                                    (new TimeSpan(afterRendering - afterViewChanged).TotalMilliseconds), this.MapZoom);

                    if (complete)               // there was no cancellation, the rendering completely finished.
                    // add the result to the scene cache.
                    {
                        lock (_cachedScene) {
                            // add the newly rendered image again.
                            _cachedScene.Clear();
                            _cachedScene.AddImage(0, float.MinValue, float.MaxValue, view.Rectangle, new byte[0], gctx.ToImage());
                        }
                        this.InvokeOnMainThread(InvalidateMap);

                        // store the previous view.
                        _previousRenderedZoom = view;
                    }

                    long after = DateTime.Now.Ticks;
                    //				if (!complete) {
                    //					OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information,"Rendering CANCELLED!",
                    //					                                new TimeSpan (after - before).TotalMilliseconds);
                    //				} else {
                    OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information,
                                                    "Rendering in {0}ms", new TimeSpan(after - before).TotalMilliseconds);
                    //				}
                    //}
                }
            }
            catch (Exception ex) {
                _cacheRenderer.Reset();
            }
        }