/// <summary> /// Sets a new visible area of map. /// </summary> /// <param name="viewBox">Bounding rectangle defining an area of view</param> /// <param name="forceRedraw">A value indicating whether a map image should be rendered /// even if the viewing area is unchanged</param> /// <param name="forceSizeFitting">A value indicating whether a view box sizes should be corrected /// to fit map control sizes</param> /// <param name="playAnimation">A value indicating whether an animation effect is played</param> public void SetViewBox(BoundingRectangle viewBox, bool forceRedraw, bool forceSizeFitting, bool playAnimation) { if (viewBox == null) { throw new ArgumentNullException("viewBox"); } if (viewBox.IsEmpty()) { if (_bitmap != null) { _bitmap = null; } this.InvalidateVisual(); } bool viewBoxChanged = WhetherViewBoxChanged(viewBox); if (forceSizeFitting) { FitViewBoxSize(viewBox); } BoundingRectangle oldViewBox = _viewBox; Rect begin; Rect end; CalcAnimationRectangles(oldViewBox, viewBox, out begin, out end); _viewBox = viewBox; if (_map != null && !viewBox.IsEmpty()) { if (viewBoxChanged || forceRedraw) { if (_animation && playAnimation && !oldViewBox.IsEmpty()) { // Need playing animation // Требуется проигрывание анимации SetViewBoxWithAnimation(begin, end); } else { if (_bitmap != null) { _bitmap = null; } RedrawMap(); } } } if (viewBoxChanged && ViewBoxChanged != null) { ViewBoxChanged(this, new ViewBoxEventArgs(_viewBox)); } }
/// <summary> /// Fit Size ViewBox /// </summary> /// <param name="viewBox"></param> private void FitViewBoxSize(BoundingRectangle viewBox) { if (viewBox == null) { return; } if (viewBox.IsEmpty()) { return; } double dx = 0; double dy = 0; if (ActualWidth / ActualHeight > viewBox.Width / viewBox.Height) { dy = -(viewBox.Height - ActualHeight / ActualWidth * viewBox.Width); } else { dx = -(viewBox.Width - ActualWidth / ActualHeight * viewBox.Height); } // Sets a bounds of all shapes in file viewBox.SetBounds(viewBox.MinX, viewBox.MinY, viewBox.MaxX + dx, viewBox.MaxY + dy); }
private void buildAndSaveIndex(MapAround.Mapping.FeatureType featureType, BoundingRectangle b, IndexSettings settings, IEnumerable <Feature> features) { ISpatialIndex index = null; if (b.IsEmpty()) { b = new BoundingRectangle(0, 0, 0, 0); } if (settings.IndexType == "QuadTree") { index = new QuadTree(b); } if (index == null) { index = new KDTree(b); } index.MaxDepth = settings.MaxDepth; index.BoxSquareThreshold = settings.BoxSquareThreshold; index.MinObjectCount = settings.MinFeatureCount; index.Build(features); _cacheAccessor.SaveFeaturesIndex(index, featureType); }
private KDTree getCrossPointsIndex(Polyline polyline) { List <MonotoneChain> chains = new List <MonotoneChain>(); foreach (LinePath path in polyline.Paths) { path.AppendMonotoneChains(chains); } List <SDMinCrossPoint> crossPoints = new List <SDMinCrossPoint>(); for (int i = 0; i < chains.Count - 1; i++) { for (int j = i + 1; j < chains.Count; j++) { if (chains[i].BoundsIntersect(chains[j])) { List <ICoordinate> points = chains[i].GetCrossPoints(chains[j]); foreach (ICoordinate p in points) { bool isChainIBoundsPoint = p.ExactEquals(chains[i].FirstPoint) || p.ExactEquals(chains[i].LastPoint); bool isChainJBoundsPoint = p.ExactEquals(chains[j].FirstPoint) || p.ExactEquals(chains[j].LastPoint); if (!(isChainIBoundsPoint && isChainJBoundsPoint)) { SDMinCrossPoint cp = new SDMinCrossPoint(); cp.Point = p; cp.BoundingRectangle = new PointD(p).GetBoundingRectangle(); cp.BoundingRectangle.Grow(PlanimetryAlgorithms.Tolerance); crossPoints.Add(cp); } } } } } BoundingRectangle br = new BoundingRectangle(); foreach (SDMinCrossPoint p in crossPoints) { br.Join(p.BoundingRectangle); } KDTree result = new KDTree(br); result.MaxDepth = 10; result.MinObjectCount = 10; if (br.IsEmpty()) { br.Join(PlanimetryEnvironment.NewCoordinate(0, 0)); } result.BoxSquareThreshold = br.Width * br.Height / 10000; result.Build(crossPoints); return(result); }
/// <summary> /// Has been modified ViewBox /// </summary> /// <param name="newViewBox">The new state ViewBox</param> /// <returns></returns> private bool WhetherViewBoxChanged(BoundingRectangle newViewBox) { if (newViewBox.IsEmpty() ^ _viewBox.IsEmpty()) { return(true); } if (!newViewBox.IsEmpty() && !_viewBox.IsEmpty()) { if (newViewBox.MinX != _viewBox.MinX || newViewBox.MaxX != _viewBox.MaxX || newViewBox.MinY != _viewBox.MinY || newViewBox.MaxY != _viewBox.MaxY) { return(true); } } return(false); }
/// <summary> /// Adds objects, which bounding rectangles intersect /// specified rectangle, to the list. /// </summary> /// <param name="box">A bounding rectangle defining queryable area</param> /// <param name="objects">A list for adding objects</param> public void QueryObjectsInRectangle <T>(BoundingRectangle box, IList <T> objects) where T : IIndexable { if (box.IsEmpty()) { return; } _root.QueryObjectsInRectangle(box, objects); }
/// <summary>Проверка записи на нахождение границ фигуры в указанной области</summary> /// <param name="bounds">Границы области</param> /// <param name="record">Запись shape-файла</param> /// <returns></returns> protected static bool IsRecordInView(BoundingRectangle bounds, ShapeFileRecord record) { if (bounds != null && !bounds.IsEmpty()) { if (!bounds.Intersects( new BoundingRectangle(PlanimetryEnvironment.NewCoordinate(record.MinX, record.MinY), PlanimetryEnvironment.NewCoordinate(record.MaxX, record.MaxY)))) return false; } return true; }
private static bool isRecordInView(BoundingRectangle bounds, ShapeFileRecord record) { if (bounds != null && !bounds.IsEmpty()) { if (!bounds.Intersects( new BoundingRectangle(PlanimetryEnvironment.NewCoordinate(record.MinX, record.MinY), PlanimetryEnvironment.NewCoordinate(record.MaxX, record.MaxY)))) { return(false); } } return(true); }
/// <summary> /// Initializes a new instance of MapAround.Indexing.QuadTree. /// </summary> /// <param name="indexedSpace">A bounding rectangle defining the extent of spatial index</param> public QuadTree(BoundingRectangle indexedSpace) { if (indexedSpace == null) { throw new ArgumentNullException("indexedSpace"); } if (indexedSpace.IsEmpty()) { throw new ArgumentException("Indexed space should not be empty", "indexedSpace"); } _indexedSpace = indexedSpace; _root = new QuadTreeNode(this, getMinBoundingQuad(indexedSpace)); }
/// <summary> /// Adds the features retrieved from cache to the receiver. /// </summary> /// <param name="processAttributes">A value indicating whether the attributes will be processed or not</param> /// <param name="cacheAccessor">Cache accessor instance</param> /// <param name="fr">An object that receives the retrieved features</param> /// <param name="bounds">Rectangle that defines a query region</param> /// <returns>Number of retrieved features</returns> public static int FillFromCache(IFeatureCollectionCacheAccessor cacheAccessor, IFeatureReceiver fr, BoundingRectangle bounds, bool processAttributes) { ISpatialIndex pointsIndex = cacheAccessor.RestoreFeaturesIndex(MapAround.Mapping.FeatureType.Point); ISpatialIndex polylinesIndex = cacheAccessor.RestoreFeaturesIndex(MapAround.Mapping.FeatureType.Polyline); ISpatialIndex polygonsIndex = cacheAccessor.RestoreFeaturesIndex(MapAround.Mapping.FeatureType.Polygon); BoundingRectangle b; if (!bounds.IsEmpty()) { b = bounds.GetBoundingRectangle(); } else { b = new BoundingRectangle(); b.Join(pointsIndex.IndexedSpace); b.Join(polylinesIndex.IndexedSpace); b.Join(polygonsIndex.IndexedSpace); } List <Feature> points = new List <Feature>(); pointsIndex.QueryObjectsInRectangle(bounds, points); List <Feature> polylines = new List <Feature>(); polylinesIndex.QueryObjectsInRectangle(bounds, polylines); List <Feature> polygons = new List <Feature>(); polygonsIndex.QueryObjectsInRectangle(bounds, polygons); points.ForEach(point => fr.AddFeature((Feature)point.Clone())); polylines.ForEach(polyline => fr.AddFeature((Feature)polyline.Clone())); polygons.ForEach(polygon => fr.AddFeature((Feature)polygon.Clone())); if (processAttributes) { fr.FeatureAttributeNames.Clear(); IList <string> attributeNames = cacheAccessor.RestoreAttributeNames(); foreach (string s in attributeNames) { fr.FeatureAttributeNames.Add(s); } } return(points.Count + polylines.Count + polygons.Count); }
/// <summary> /// Читает запись представляющую точку. /// </summary> /// <param name="file">Входной поток</param> /// <param name="record">Запись Shape-файла в которую будет помещена прочитанная информация</param> /// <param name="bounds">Ограничивающий прямоугольник, с которым должен пересекаться ограничивающий прямоугольник записи</param> public override bool Read(/*BigEndianBinaryReader*/Stream file, BoundingRectangle bounds, ShapeFileRecord record) { ICoordinate p = PlanimetryEnvironment.NewCoordinate(0, 0); p.X = file.ReadDouble();// ShapeFile.ReadDouble64_LE(stream); p.Y = file.ReadDouble();// ShapeFile.ReadDouble64_LE(stream); if (bounds != null && !bounds.IsEmpty() && !bounds.ContainsPoint(p)) return false; record.Points.Add(p); record.MinX = p.X; record.MinY = p.Y; record.MaxX = record.MinX; record.MaxY = record.MinY; return true; }
/// <summary> ///Calculation of the animation Rectangle /// </summary> /// <param name="oldViewBox"></param> /// <param name="viewBox"></param> /// <param name="begin"></param> /// <param name="end"></param> private void CalcAnimationRectangles(BoundingRectangle oldViewBox, BoundingRectangle viewBox, out Rect begin, out Rect end) { begin = new Rect(); end = new Rect(); if (!oldViewBox.IsEmpty()) { begin = MapViewBoxToClientRectangle(oldViewBox); if (_startAnimationOffsetX != 0 || _startAnimationOffsetY != 0) { begin = new Rect(new Point(_startAnimationOffsetX, _startAnimationOffsetY), begin.Size); } } if (!viewBox.IsEmpty() && !_viewBox.IsEmpty()) { end = MapViewBoxToClientRectangle(viewBox); } }
/// <summary> /// Читает запись представляющую точку. /// </summary> /// <param name="file">Входной поток</param> /// <param name="record">Запись Shape-файла в которую будет помещена прочитанная информация</param> /// <param name="bounds">Ограничивающий прямоугольник, с которым должен пересекаться ограничивающий прямоугольник записи</param> public override bool Read(/*BigEndianBinaryReader*/ Stream file, BoundingRectangle bounds, ShapeFileRecord record) { ICoordinate p = PlanimetryEnvironment.NewCoordinate(0, 0); p.X = file.ReadDouble(); // ShapeFile.ReadDouble64_LE(stream); p.Y = file.ReadDouble(); // ShapeFile.ReadDouble64_LE(stream); if (bounds != null && !bounds.IsEmpty() && !bounds.ContainsPoint(p)) { return(false); } record.Points.Add(p); record.MinX = p.X; record.MinY = p.Y; record.MaxX = record.MinX; record.MaxY = record.MinY; return(true); }
private void SetViewBox() // Метод поиска ViewBox { BoundingRectangle rectangle = _mapAroundMap.CalculateBoundingRectangle(); _initialRectangle = rectangle; if (rectangle.IsEmpty()) { return; // Расчет области данных карты } // Поправка, для того, что бы вписать данные в контрол double deltaY = rectangle.Width * MapAroundControl.Height / 2 / MapAroundControl.Width - rectangle.Height / 2; // Установка нового ViewBox MapAroundControl.SetViewBox(new BoundingRectangle(rectangle.MinX, rectangle.MinY - deltaY, rectangle.MaxX, rectangle.MaxY + deltaY)); _mapAroundMap.FeatureRenderer.FlushTitles(MapAroundControl.CreateGraphics(), rectangle, 1); InitCellMap(); InitPathLayer(); InitHpaStar(); }
/// <summary> ///Calculation of the animation Rectangle /// </summary> /// <param name="oldViewBox"></param> /// <param name="viewBox"></param> /// <param name="begin"></param> /// <param name="end"></param> private void CalcAnimationRectangles(BoundingRectangle oldViewBox, BoundingRectangle viewBox, out Rect begin, out Rect end) { begin = new Rect(); end = new Rect(); if (!oldViewBox.IsEmpty()) { begin = MapViewBoxToClientRectangle(oldViewBox); if (_startAnimationOffsetX != 0 || _startAnimationOffsetY != 0) { begin = new Rect(new Point(_startAnimationOffsetX, _startAnimationOffsetY), begin.Size); } } if (!viewBox.IsEmpty() && !_viewBox.IsEmpty()) end = MapViewBoxToClientRectangle(viewBox); }
/// <summary> /// Adds the features retrieved from cache to the receiver. /// </summary> /// <param name="processAttributes">A value indicating whether the attributes will be processed or not</param> /// <param name="cacheAccessor">Cache accessor instance</param> /// <param name="fr">An object that receives the retrieved features</param> /// <param name="bounds">Rectangle that defines a query region</param> /// <returns>Number of retrieved features</returns> public static int FillFromCache(IFeatureCollectionCacheAccessor cacheAccessor, IFeatureReceiver fr, BoundingRectangle bounds, bool processAttributes) { ISpatialIndex pointsIndex = cacheAccessor.RestoreFeaturesIndex(MapAround.Mapping.FeatureType.Point); ISpatialIndex polylinesIndex = cacheAccessor.RestoreFeaturesIndex(MapAround.Mapping.FeatureType.Polyline); ISpatialIndex polygonsIndex = cacheAccessor.RestoreFeaturesIndex(MapAround.Mapping.FeatureType.Polygon); BoundingRectangle b; if (!bounds.IsEmpty()) b = bounds.GetBoundingRectangle(); else { b = new BoundingRectangle(); b.Join(pointsIndex.IndexedSpace); b.Join(polylinesIndex.IndexedSpace); b.Join(polygonsIndex.IndexedSpace); } List<Feature> points = new List<Feature>(); pointsIndex.QueryObjectsInRectangle(bounds, points); List<Feature> polylines = new List<Feature>(); polylinesIndex.QueryObjectsInRectangle(bounds, polylines); List<Feature> polygons = new List<Feature>(); polygonsIndex.QueryObjectsInRectangle(bounds, polygons); points.ForEach(point => fr.AddFeature((Feature)point.Clone())); polylines.ForEach(polyline => fr.AddFeature((Feature)polyline.Clone())); polygons.ForEach(polygon => fr.AddFeature((Feature)polygon.Clone())); if (processAttributes) { fr.FeatureAttributeNames.Clear(); IList<string> attributeNames = cacheAccessor.RestoreAttributeNames(); foreach (string s in attributeNames) fr.FeatureAttributeNames.Add(s); } return points.Count + polylines.Count + polygons.Count; }
/// <summary> /// Sets a new visible area of map. /// </summary> /// <param name="viewBox">Bounding rectangle defining an area of view</param> /// <param name="forceRedraw">A value indicating whether a map image should be rendered /// even if the viewing area is unchanged</param> /// <param name="forceSizeFitting">A value indicating whether a view box sizes should be corrected /// to fit map control sizes</param> /// <param name="playAnimation">A value indicating whether an animation effect is played</param> public void SetViewBox(BoundingRectangle viewBox, bool forceRedraw, bool forceSizeFitting, bool playAnimation) { if (viewBox == null) throw new ArgumentNullException("viewBox"); if (viewBox.IsEmpty()) { if (_bitmap != null) _bitmap = null; this.InvalidateVisual(); } bool viewBoxChanged = WhetherViewBoxChanged(viewBox); if (forceSizeFitting) FitViewBoxSize(viewBox); BoundingRectangle oldViewBox = _viewBox; Rect begin; Rect end; CalcAnimationRectangles(oldViewBox, viewBox, out begin, out end); _viewBox = viewBox; if (_map != null && !viewBox.IsEmpty()) if (viewBoxChanged || forceRedraw) { if (_animation && playAnimation && !oldViewBox.IsEmpty()) // Need playing animation // Требуется проигрывание анимации SetViewBoxWithAnimation(begin, end); else { if (_bitmap != null) _bitmap = null; RedrawMap(); } } if (viewBoxChanged && ViewBoxChanged != null) ViewBoxChanged(this, new ViewBoxEventArgs(_viewBox)); }
/// <summary> /// Has been modified ViewBox /// </summary> /// <param name="newViewBox">The new state ViewBox</param> /// <returns></returns> private bool WhetherViewBoxChanged(BoundingRectangle newViewBox) { if (newViewBox.IsEmpty() ^ _viewBox.IsEmpty()) return true; if (!newViewBox.IsEmpty() && !_viewBox.IsEmpty()) { if (newViewBox.MinX != _viewBox.MinX || newViewBox.MaxX != _viewBox.MaxX || newViewBox.MinY != _viewBox.MinY || newViewBox.MaxY != _viewBox.MaxY) return true; } return false; }
/// <summary> /// Fit Size ViewBox /// </summary> /// <param name="viewBox"></param> private void FitViewBoxSize(BoundingRectangle viewBox) { if (viewBox == null) return; if (viewBox.IsEmpty()) return; double dx = 0; double dy = 0; if (ActualWidth / ActualHeight > viewBox.Width / viewBox.Height) dy = -(viewBox.Height - ActualHeight / ActualWidth * viewBox.Width); else dx = -(viewBox.Width - ActualWidth / ActualHeight * viewBox.Height); // Sets a bounds of all shapes in file viewBox.SetBounds(viewBox.MinX, viewBox.MinY, viewBox.MaxX + dx, viewBox.MaxY + dy); }
private void buildAndSaveIndex(MapAround.Mapping.FeatureType featureType, BoundingRectangle b, IndexSettings settings, IEnumerable<Feature> features) { ISpatialIndex index = null; if (b.IsEmpty()) b = new BoundingRectangle(0, 0, 0, 0); if (settings.IndexType == "QuadTree") index = new QuadTree(b); if (index == null) index = new KDTree(b); index.MaxDepth = settings.MaxDepth; index.BoxSquareThreshold = settings.BoxSquareThreshold; index.MinObjectCount = settings.MinFeatureCount; index.Build(features); _cacheAccessor.SaveFeaturesIndex(index, featureType); }
private KDTree getCrossPointsIndex(Polyline polyline) { List<MonotoneChain> chains = new List<MonotoneChain>(); foreach (LinePath path in polyline.Paths) path.AppendMonotoneChains(chains); List<SDMinCrossPoint> crossPoints = new List<SDMinCrossPoint>(); for (int i = 0; i < chains.Count - 1; i++) for (int j = i + 1; j < chains.Count; j++) if (chains[i].BoundsIntersect(chains[j])) { List<ICoordinate> points = chains[i].GetCrossPoints(chains[j]); foreach (ICoordinate p in points) { bool isChainIBoundsPoint = p.ExactEquals(chains[i].FirstPoint) || p.ExactEquals(chains[i].LastPoint); bool isChainJBoundsPoint = p.ExactEquals(chains[j].FirstPoint) || p.ExactEquals(chains[j].LastPoint); if (!(isChainIBoundsPoint && isChainJBoundsPoint)) { SDMinCrossPoint cp = new SDMinCrossPoint(); cp.Point = p; cp.BoundingRectangle = new PointD(p).GetBoundingRectangle(); cp.BoundingRectangle.Grow(PlanimetryAlgorithms.Tolerance); crossPoints.Add(cp); } } } BoundingRectangle br = new BoundingRectangle(); foreach (SDMinCrossPoint p in crossPoints) br.Join(p.BoundingRectangle); KDTree result = new KDTree(br); result.MaxDepth = 10; result.MinObjectCount = 10; if (br.IsEmpty()) br.Join(PlanimetryEnvironment.NewCoordinate(0, 0)); result.BoxSquareThreshold = br.Width * br.Height / 10000; result.Build(crossPoints); return result; }