protected virtual DataRect CoerceVisible(DataRect newVisible) { if (Plotter == null) { return newVisible; } bool isDefaultValue = newVisible == (DataRect)VisibleProperty.DefaultMetadata.DefaultValue; if (isDefaultValue) { newVisible = DataRect.Empty; } if (isDefaultValue && IsFittedToView) { // determining content bounds DataRect bounds = DataRect.Empty; foreach (var item in contentBoundsHosts) { IPlotterElement plotterElement = item as IPlotterElement; if (plotterElement == null) continue; if (plotterElement.Plotter == null) continue; var plotter = (Plotter2D)plotterElement.Plotter; var visual = plotter.VisualBindings[plotterElement]; if (visual.Visibility == Visibility.Visible) { DataRect contentBounds = Viewport2D.GetContentBounds(item); if (contentBounds.Width.IsNaN() || contentBounds.Height.IsNaN()) continue; bounds.UnionFinite(contentBounds); } } if (useApproximateContentBoundsComparison) { var intersection = prevContentBounds; intersection.Intersect(bounds); double currSquare = bounds.GetSquare(); double prevSquare = prevContentBounds.GetSquare(); double intersectionSquare = intersection.GetSquare(); double squareTopLimit = 1 + maxContentBoundsComparisonMistake; double squareBottomLimit = 1 - maxContentBoundsComparisonMistake; if (intersectionSquare != 0) { double currRatio = currSquare / intersectionSquare; double prevRatio = prevSquare / intersectionSquare; if (squareBottomLimit < currRatio && currRatio < squareTopLimit && squareBottomLimit < prevRatio && prevRatio < squareTopLimit) { bounds = prevContentBounds; } } } prevContentBounds = bounds; UnitedContentBounds = bounds; // applying fit-to-view constraints bounds = fitToViewConstraints.Apply(Visible, bounds, this); // enlarging if (!bounds.IsEmpty) { bounds = CoordinateUtilities.RectZoom(bounds, bounds.GetCenter(), clipToBoundsEnlargeFactor); } else { bounds = (DataRect)VisibleProperty.DefaultMetadata.DefaultValue; } newVisible.Union(bounds); } if (newVisible.IsEmpty) { newVisible = (DataRect)VisibleProperty.DefaultMetadata.DefaultValue; } else if (newVisible.Width == 0 || newVisible.Height == 0) { DataRect defRect = (DataRect)VisibleProperty.DefaultMetadata.DefaultValue; Size size = newVisible.Size; Point location = newVisible.Location; if (newVisible.Width == 0) { size.Width = defRect.Width; location.X -= size.Width / 2; } if (newVisible.Height == 0) { size.Height = defRect.Height; location.Y -= size.Height / 2; } newVisible = new DataRect(location, size); } // apply domain constraint newVisible = domainConstraint.Apply(Visible, newVisible, this); // apply other restrictions if (enforceConstraints) newVisible = constraints.Apply(Visible, newVisible, this); // applying transform's data domain constraint if (!transform.DataTransform.DataDomain.IsEmpty) { var newDataRect = newVisible.ViewportToData(transform); newDataRect = DataRect.Intersect(newDataRect, transform.DataTransform.DataDomain); newVisible = newDataRect.DataToViewport(transform); } if (newVisible.IsEmpty) newVisible = new Rect(0, 0, 1, 1); return newVisible; }
protected void OnRender() { if (DesignerProperties.GetIsInDesignMode(this)) return; if (plotter == null) return; panel.Children.Clear(); freeChildren = new List<MapElement>(panel.Children.Count); for (int i = 0; i < panel.Children.Count; i++) { freeChildren.Add((MapElement)panel.Children[i]); } rendering = true; invalidatePending = false; var transform = plotter.Viewport.Transform; Rect output = plotter.Viewport.Output; DataRect visible = plotter.Viewport.Visible; visibleBounds = visible; drawnBounds = DataRect.Empty; var tileInfos = GetVisibleTiles(); var lowerTilesList = GetLoadedLowerTiles(tileInfos); // displaying lower tiles foreach (var tile in lowerTilesList) { if (server.IsLoaded(tile)) { var bmp = server[tile]; DataRect visibleRect = tileProvider.GetTileBounds(tile); DrawImage(bmp, visibleRect, tile); } else { server.BeginLoadImage(tile); } } int count = 0; foreach (var tileInfo in tileInfos) { drawnBounds.Union(tileInfo.VisibleBounds); count++; if (server.IsLoaded(tileInfo.Tile)) { var bmp = server[tileInfo.Tile]; DrawImage(bmp, tileInfo.VisibleBounds, tileInfo.Tile); } else { server.BeginLoadImage(tileInfo.Tile); } } showsWholeMap = count == MapTileProvider.GetTotalTilesCount(tileProvider.Level); foreach (var item in freeChildren) { panel.Children.Remove(item); pool.Put(item); } foreach (MapElement item in panel.Children) { if (item.Bitmap == null) { panel.Children.Remove(item); pool.Put(item); } } rendering = false; Debug.WriteLine("Drawn " + Environment.TickCount); }