コード例 #1
0
        private void DrawTile(MapArgs args, TileInfo info, Resolution resolution, byte[] buffer, TileReprojector tr = null)
        {
            if (buffer == null || buffer.Length == 0)
                return;

            tr = tr ?? new TileReprojector(args, _projection, _targetProjection);

            using (var bitmap = (Bitmap)Image.FromStream(new MemoryStream(buffer)))
            {
                var inWorldFile = new Reprojection.WorldFile(resolution.UnitsPerPixel, 0, 
                                                0, -resolution.UnitsPerPixel,
                                                info.Extent.MinX, info.Extent.MaxY);

                Reprojection.WorldFile outWorldFile;
                Bitmap outBitmap;


                tr.Reproject(inWorldFile, bitmap, out outWorldFile, out outBitmap);
                if (outWorldFile == null) return;

                var lt = args.ProjToPixel(outWorldFile.ToGround(0, 0));
                var rb = args.ProjToPixel(outWorldFile.ToGround(outBitmap.Width, outBitmap.Height));
                var rect = new Rectangle(lt, Size.Subtract(new Size(rb), new Size(lt)));

                args.Device.DrawImage(outBitmap, rect, 0, 0, outBitmap.Width, outBitmap.Height,
                    GraphicsUnit.Pixel, _imageAttributes);

                if (outBitmap != bitmap) outBitmap.Dispose();
                if (FrameTile)
                {
                    if (FramePen != null)
                        args.Device.DrawRectangle(FramePen, rect);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// This draws content from the specified geographic regions onto the specified graphics
        /// object specified by MapArgs.
        /// </summary>
        public void DrawRegions(MapArgs args, List<Extent> regions)
        {

            // If this layer is not marked visible, exit
            if (!IsVisible) return;

            _stopwatch.Reset();

            var region = regions.FirstOrDefault() ?? args.GeographicExtents;

            if (!Monitor.TryEnter(_drawLock))
                return;
            
                LogManager.DefaultLogManager.LogMessage("MAP   : " + region, DialogResult.OK);

                // If we have a target projection, so project extent to providers extent
                var geoExtent = _targetProjection == null
                                    ? region
                                    : region.Intersection(Extent).Reproject(_targetProjection, _projectionInfo);

                LogManager.DefaultLogManager.LogMessage("SOURCE: " + geoExtent, DialogResult.OK);

                if (geoExtent.IsEmpty())
                {
                    LogManager.DefaultLogManager.LogMessage("Skipping because extent is empty!", DialogResult.OK);
                    Monitor.Exit(_drawLock);
                    return; 
                }

                BruTile.Extent extent;
                try
                {
                     extent = ToBrutileExtent(geoExtent);
                }
                catch (Exception ex)
                {
                    LogManager.DefaultLogManager.Exception(ex);
                    Monitor.Exit(_drawLock);
                    return;
                }

                if (double.IsNaN(extent.Area))
                {
                    LogManager.DefaultLogManager.LogMessage("Skipping because extent is empty!", DialogResult.OK);
                    Monitor.Exit(_drawLock);
                    return;
                }

                var pixelSize = extent.Width/args.ImageRectangle.Width;

                var tileSource = _configuration.TileSource;
                var schema = tileSource.Schema;
                var level = _level = Utilities.GetNearestLevel(schema.Resolutions, pixelSize);
                
                _tileFetcher.Clear();
                var tiles = new List<TileInfo>(Sort(schema.GetTileInfos(extent, level), geoExtent.Center));
                var waitHandles = new List<WaitHandle>();
                var tilesNotImmediatelyDrawn = new List<TileInfo>();

                LogManager.DefaultLogManager.LogMessage(string.Format("Trying to get #{0} tiles: ", tiles.Count),
                                                        DialogResult.OK);

                // Set up Tile reprojector
                var tr = new TileReprojector(args, _projectionInfo, _targetProjection);


                var sw = new System.Diagnostics.Stopwatch();
                sw.Start();

                // Store the current transformation
                var transform = args.Device.Transform;
                var resolution = schema.Resolutions[level];
                foreach (var info in tiles)
                {
                    var are = _tileFetcher.AsyncMode ? null : new AutoResetEvent(false);
                    var imageData = _tileFetcher.GetTile(info, are);
                    if (imageData != null)
                    {
                        //DrawTile
                        DrawTile(args, info, resolution, imageData, tr);
                        continue;
                    }
                    if (are == null) continue;

                    waitHandles.Add(are);
                    tilesNotImmediatelyDrawn.Add(info);
                }

                //Wait for tiles
                foreach (var handle in waitHandles)
                    handle.WaitOne();

                //Draw the tiles that were not present at the moment requested
                foreach (var tileInfo in tilesNotImmediatelyDrawn)
                    DrawTile(args, tileInfo, resolution, _tileFetcher.GetTile(tileInfo, null), tr);

                //Restore the transform
                args.Device.Transform = transform;

                sw.Stop();
                
                System.Diagnostics.Debug.WriteLine("{0} ms", sw.ElapsedMilliseconds);
                System.Diagnostics.Debug.Write(string.Format("Trying to render #{0} tiles: ", tiles.Count));

                LogManager.DefaultLogManager.LogMessage(string.Format("{0} ms", sw.ElapsedMilliseconds), DialogResult.OK);
                //if (InvalidRegion != null)
                //    Invalidate();

                //_stopwatch.Restart();
                Monitor.Exit(_drawLock);
        }