/// <summary> /// Raises the draw event. /// </summary> /// <param name="canvas">Canvas.</param> protected override void OnDraw(global::Android.Graphics.Canvas canvas) { base.OnDraw(canvas); // set the height/width. if (_surfaceHeight != canvas.Height || _surfaceWidth != canvas.Width) { _surfaceHeight = canvas.Height; _surfaceWidth = canvas.Width; // trigger rendering. this.TriggerRendering(); } // render only the cached scene. canvas.DrawColor(new global::Android.Graphics.Color(_backgroundColor)); View2D view = this.CreateView(); float zoomFactor = (float)this.Map.Projection.ToZoomFactor(this.MapZoom); _renderer.SceneRenderer.Render( canvas, view, zoomFactor, new Primitive2D[] { _onScreenBuffer }); }
/// <summary> /// Raises the draw event. /// </summary> /// <param name="canvas">Canvas.</param> protected override void OnDraw(global::Android.Graphics.Canvas canvas) { base.OnDraw(canvas); // render only the cached scene. lock (_scene) { canvas.DrawColor(new global::Android.Graphics.Color(_scene.BackColor)); _renderer.SceneRenderer.Render( canvas, _scene, this.CreateView()); } }
/// <summary> /// Raises the draw event. /// </summary> /// <param name="canvas">Canvas.</param> protected override void OnDraw(global::Android.Graphics.Canvas canvas) { try { base.OnDraw(canvas); if (_renderingSuspended) { // do nothing when rendering is suspended. return; } // set the height/width. if (_surfaceHeight != canvas.Height || _surfaceWidth != canvas.Width) { _surfaceHeight = canvas.Height; _surfaceWidth = canvas.Width; // make sure markers are in the correct position too. _mapView.NotifyMapChange(this.SurfaceWidth, this.SurfaceHeight, this.CreateView(), this.Map.Projection); // trigger rendering. this.TriggerRendering(); // raise map initialized. _mapView.RaiseMapInitialized(); } if (_onScreenBuffer != null) { // there is a buffer. // render only the cached scene. canvas.DrawColor(new global::Android.Graphics.Color(_backgroundColor)); View2D view = this.CreateView(); float zoomFactor = (float)this.Map.Projection.ToZoomFactor(this.MapZoom); _renderer.SceneRenderer.Render( canvas, view, zoomFactor, new Primitive2D[] { _onScreenBuffer }); } } catch (Exception ex) { OsmSharp.Logging.Log.TraceEvent("MapViewSurface", TraceEventType.Critical, string.Format("An unhandled exception occured:{0}", ex.ToString())); } }
/// <summary> /// Raises the draw event. /// </summary> /// <param name="canvas">Canvas.</param> protected override void OnDraw(global::Android.Graphics.Canvas canvas) { base.OnDraw(canvas); // long before = DateTime.Now.Ticks; // render only the cached scene. lock (_scene) { // OsmSharp.IO.Output.OutputStreamHost.WriteLine ("OnDraw"); canvas.DrawColor(new global::Android.Graphics.Color(_scene.BackColor)); _renderer.SceneRenderer.Render( canvas, _scene, _renderer.Create(canvas.Width, canvas.Height, this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoomLevel), this.MapCenter, _invertX, _invertY)); } // long after = DateTime.Now.Ticks; // OsmSharp.IO.Output.OutputStreamHost.WriteLine(string.Format("Rendering in {0}ms", // new TimeSpan (after - before).TotalMilliseconds)); }
/// <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. _cacheRenderer.Density = this.MapScaleFactor; bool complete = _cacheRenderer.Render(canvas, _map.Projection, 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())); } }
/// <summary> /// Renders the current complete scene. /// </summary> void Render() { if (_cacheRenderer.IsRunning) { _cacheRenderer.CancelAndWait(); } // make sure only on thread at the same time is using the renderer. lock (_cacheRenderer) { double extra = 1.25; // build the layers list. var layers = new List <ILayer> (); for (int layerIdx = 0; layerIdx < this.Map.LayerCount; layerIdx++) { // get the layer. layers.Add(this.Map[layerIdx]); } // add the internal layers. layers.Add(_makerLayer); // create a new cache if size has changed. if (_canvasBitmap == null || _canvasBitmap.Width != (int)(this.Width * extra) || _canvasBitmap.Height != (int)(this.Height * extra)) { // create a bitmap and render there. _canvasBitmap = global::Android.Graphics.Bitmap.CreateBitmap((int)(this.Width * extra), (int)(this.Height * extra), global::Android.Graphics.Bitmap.Config.Argb8888); } else { // clear the cache??? } // create and reset the canvas. global::Android.Graphics.Canvas canvas = new global::Android.Graphics.Canvas(_canvasBitmap); canvas.DrawColor(new global::Android.Graphics.Color( SimpleColor.FromKnownColor(KnownColor.Transparent).Value)); // create the view. View2D view = _cacheRenderer.Create(canvas.Width, canvas.Height, this.Map, (float)this.Map.Projection.ToZoomFactor(this.MapZoomLevel), this.MapCenter, _invertX, _invertY); long before = DateTime.Now.Ticks; OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information, "Rendering Start"); // notify the map that the view has changed. this.Map.ViewChanged((float)this.Map.Projection.ToZoomFactor(this.MapZoomLevel), 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.MapZoomLevel); // add the current canvas to the scene. double left = view.LeftTop [0]; double right = view.RightTop [0]; double top = view.LeftTop [1]; double bottom = view.LeftBottom [1]; uint canvasId = _scene.AddImage(-1, float.MinValue, float.MaxValue, left, top, right, bottom, new byte[0], _canvasBitmap); // does the rendering. bool complete = _cacheRenderer.Render(canvas, 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.MapZoomLevel); if (complete) { // there was no cancellation, the rendering completely finished. // add the result to the scene cache. lock (_scene) { // if (_previousCache.HasValue) { // _scene.Remove (_previousCache.Value); // } // _scene.Remove (canvasId); // // add the newly rendered image again. _scene.Clear(); //_previousCache = BoxF2D viewBox = view.OuterBox; _scene.AddImage(0, float.MinValue, float.MaxValue, viewBox.Min[0], viewBox.Min[1], viewBox.Max[0], viewBox.Max[1], new byte[0], _canvasBitmap); // switch cache and canvas to prevent re-allocation of bitmaps. global::Android.Graphics.Bitmap newCanvas = _cache; _cache = _canvasBitmap; _canvasBitmap = newCanvas; } } this.PostInvalidate(); long after = DateTime.Now.Ticks; if (!complete) { OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information, "Rendering in {0}ms after cancellation!", 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); } } }
/// <summary> /// Renders the current complete scene. /// </summary> void Render() { if (_cacheRenderer.IsRunning) { _cacheRenderer.CancelAndWait (); } // make sure only on thread at the same time is using the renderer. lock (_cacheRenderer) { double extra = 1.25; // build the layers list. var layers = new List<ILayer> (); for (int layerIdx = 0; layerIdx < this.Map.LayerCount; layerIdx++) { // get the layer. layers.Add (this.Map[layerIdx]); } // add the internal layers. layers.Add (_makerLayer); // create a new cache if size has changed. if (_canvasBitmap == null || _canvasBitmap.Width != (int)(this.Width * extra) || _canvasBitmap.Height != (int)(this.Height * extra)) { // create a bitmap and render there. _canvasBitmap = global::Android.Graphics.Bitmap.CreateBitmap ((int)(this.Width * extra), (int)(this.Height * extra), global::Android.Graphics.Bitmap.Config.Argb8888); } else { // clear the cache??? } // create and reset the canvas. global::Android.Graphics.Canvas canvas = new global::Android.Graphics.Canvas (_canvasBitmap); canvas.DrawColor (new global::Android.Graphics.Color( SimpleColor.FromKnownColor(KnownColor.Transparent).Value)); // create the view. double[] sceneCenter = this.Map.Projection.ToPixel(this.MapCenter.Latitude, this.MapCenter.Longitude); float sceneZoomFactor = (float)this.Map.Projection.ToZoomFactor(this.MapZoom); // create the view for this control. View2D view = View2D.CreateFrom((float)sceneCenter[0], (float)sceneCenter[1], this.Width * extra, this.Height * extra, sceneZoomFactor, _invertX, _invertY, this.MapTilt); long before = DateTime.Now.Ticks; OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information, "Rendering Start"); // 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); // add the current canvas to the scene. _scene.AddImage (-1, float.MaxValue, float.MinValue, view.Rectangle, new byte[0], _canvasBitmap); // does the rendering. bool complete = _cacheRenderer.Render (canvas, 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 (_scene) { // add the newly rendered image again. _scene.Clear (); _scene.AddImage (0, float.MinValue, float.MaxValue, view.Rectangle, new byte[0], _canvasBitmap); // switch cache and canvas to prevent re-allocation of bitmaps. global::Android.Graphics.Bitmap newCanvas = _cache; _cache = _canvasBitmap; _canvasBitmap = newCanvas; } } this.PostInvalidate (); long after = DateTime.Now.Ticks; } }
/// <summary> /// Renders the current complete scene. /// </summary> void Render() { if (_cacheRenderer.IsRunning) { _cacheRenderer.CancelAndWait(); } // make sure only on thread at the same time is using the renderer. lock (_cacheRenderer) { double extra = 1.25; // build the layers list. var layers = new List <ILayer> (); for (int layerIdx = 0; layerIdx < this.Map.LayerCount; layerIdx++) { // get the layer. layers.Add(this.Map[layerIdx]); } // add the internal layers. layers.Add(_makerLayer); // create a new cache if size has changed. if (_canvasBitmap == null || _canvasBitmap.Width != (int)(this.Width * extra) || _canvasBitmap.Height != (int)(this.Height * extra)) { // create a bitmap and render there. _canvasBitmap = global::Android.Graphics.Bitmap.CreateBitmap((int)(this.Width * extra), (int)(this.Height * extra), global::Android.Graphics.Bitmap.Config.Argb8888); } else { // clear the cache??? } // create and reset the canvas. global::Android.Graphics.Canvas canvas = new global::Android.Graphics.Canvas(_canvasBitmap); canvas.DrawColor(new global::Android.Graphics.Color( SimpleColor.FromKnownColor(KnownColor.Transparent).Value)); // create the view. double[] sceneCenter = this.Map.Projection.ToPixel(this.MapCenter.Latitude, this.MapCenter.Longitude); float sceneZoomFactor = (float)this.Map.Projection.ToZoomFactor(this.MapZoom); // create the view for this control. View2D view = View2D.CreateFrom((float)sceneCenter[0], (float)sceneCenter[1], this.Width * extra, this.Height * extra, sceneZoomFactor, _invertX, _invertY, this.MapTilt); long before = DateTime.Now.Ticks; OsmSharp.Logging.Log.TraceEvent("OsmSharp.Android.UI.MapView", System.Diagnostics.TraceEventType.Information, "Rendering Start"); // 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); // add the current canvas to the scene. _scene.AddImage(-1, float.MaxValue, float.MinValue, view.Rectangle, new byte[0], _canvasBitmap); // does the rendering. bool complete = _cacheRenderer.Render(canvas, 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 (_scene) { // add the newly rendered image again. _scene.Clear(); _scene.AddImage(0, float.MinValue, float.MaxValue, view.Rectangle, new byte[0], _canvasBitmap); // switch cache and canvas to prevent re-allocation of bitmaps. global::Android.Graphics.Bitmap newCanvas = _cache; _cache = _canvasBitmap; _canvasBitmap = newCanvas; } } this.PostInvalidate(); long after = DateTime.Now.Ticks; } }
/// <summary> /// Renders the current complete scene. /// </summary> private void Render() { if (_cacheRenderer.IsRunning) { _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. layers.Add (this.Map[layerIdx]); } // add the internal layers. layers.Add (_makerLayer); // get old image if available. global::Android.Graphics.Bitmap image = null; if (_offScreenBuffer != null) { image = _offScreenBuffer.Tag as global::Android.Graphics.Bitmap; } if (this.SurfaceHeight == 0) { return; } // resize image if needed. float size = System.Math.Max(this.SurfaceHeight, this.SurfaceWidth); if (image == null || image.Width != (int)(size * _extra) || image.Height != (int)(size * _extra)) { // create a bitmap and render there. image = global::Android.Graphics.Bitmap.CreateBitmap((int)(size * _extra), (int)(size * _extra), global::Android.Graphics.Bitmap.Config.Argb8888); } // create and reset the canvas. global::Android.Graphics.Canvas canvas = new global::Android.Graphics.Canvas (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. View2D view = View2D.CreateFrom((float)sceneCenter[0], (float)sceneCenter[1], size * _extra, size * _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. 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", 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}", (new TimeSpan(afterRendering - afterViewChanged).TotalMilliseconds), this.MapZoom); if(complete) { // there was no cancellation, the rendering completely finished. // add the result to the scene cache. // add the newly rendered image again. _offScreenBuffer = new ImageTilted2D(view.Rectangle, new byte[0], float.MinValue, float.MaxValue); _offScreenBuffer.Tag = image; var temp = _onScreenBuffer; _onScreenBuffer = _offScreenBuffer; _offScreenBuffer = temp; } // notify the the current surface of the new rendering. this.PostInvalidate(); long after = DateTime.Now.Ticks; if (complete) { // report a successfull render to listener. _listener.NotifyRenderSuccess(view, mapZoom, (int)new TimeSpan(after - before).TotalMilliseconds); } } }
/// <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())); } }
/// <summary> /// Renders the current complete scene. /// </summary> private void Render() { if (_cacheRenderer.IsRunning) { _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. layers.Add(this.Map[layerIdx]); } // add the internal layers. layers.Add(_makerLayer); // get old image if available. global::Android.Graphics.Bitmap image = null; if (_offScreenBuffer != null) { image = _offScreenBuffer.Tag as global::Android.Graphics.Bitmap; } if (this.SurfaceHeight == 0) { return; } // resize image if needed. float size = System.Math.Max(this.SurfaceHeight, this.SurfaceWidth); if (image == null || image.Width != (int)(size * _extra) || image.Height != (int)(size * _extra)) { // create a bitmap and render there. image = global::Android.Graphics.Bitmap.CreateBitmap((int)(size * _extra), (int)(size * _extra), global::Android.Graphics.Bitmap.Config.Argb8888); } // create and reset the canvas. global::Android.Graphics.Canvas canvas = new global::Android.Graphics.Canvas(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. View2D view = View2D.CreateFrom((float)sceneCenter[0], (float)sceneCenter[1], size * _extra, size * _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. 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", 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}", (new TimeSpan(afterRendering - afterViewChanged).TotalMilliseconds), this.MapZoom); if (complete) { // there was no cancellation, the rendering completely finished. // add the result to the scene cache. // add the newly rendered image again. _offScreenBuffer = new ImageTilted2D(view.Rectangle, new byte[0], float.MinValue, float.MaxValue); _offScreenBuffer.Tag = image; var temp = _onScreenBuffer; _onScreenBuffer = _offScreenBuffer; _offScreenBuffer = temp; } // notify the the current surface of the new rendering. this.PostInvalidate(); long after = DateTime.Now.Ticks; if (complete) { // report a successfull render to listener. _listener.NotifyRenderSuccess(view, mapZoom, (int)new TimeSpan(after - before).TotalMilliseconds); } } }