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); }
private void boundsChanged() { BoundingRectangle br = new BoundingRectangle(); if (_segments.Count > 0) { br.Join(_segments[0].V1); br.Join(_segments[0].V2); br.Join(_segments[_segments.Count - 1].V1); br.Join(_segments[_segments.Count - 1].V2); } _boundingRectangle = br; }
/// <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); }
private void addFeaturesToCache(IFeatureReceiver fr, List <Feature> points, List <Feature> multiPoints, List <Feature> polylines, List <Feature> polygons) { _cacheAccessor.Key = fr.Alias; if (!_cacheAccessor.ExistsInCache) { BoundingRectangle b = new BoundingRectangle(); List <Feature> pts = new List <Feature>(); foreach (Feature feature in points) { b.Join(feature.BoundingRectangle); pts.Add(feature); } foreach (Feature feature in multiPoints) { b.Join(feature.BoundingRectangle); pts.Add(feature); } //buildAndSaveIndex(MapAround.Mapping.FeatureType.Point, b, fr.DefaultPointsIndexSettings, pts); b = new BoundingRectangle(); foreach (Feature feature in polylines) { b.Join(feature.BoundingRectangle); } //buildAndSaveIndex(MapAround.Mapping.FeatureType.Polyline, b, fr.DefaultPolylinesIndexSettings, polylines); b = new BoundingRectangle(); foreach (Feature feature in polygons) { b.Join(feature.BoundingRectangle); } //buildAndSaveIndex(MapAround.Mapping.FeatureType.Polygon, b, fr.DefaultPolygonsIndexSettings, polygons); if (_processAttributes) { _cacheAccessor.SaveAttributeNames(fr.FeatureAttributeNames); } } }
/// <summary> /// Performs a rubbersheeting transformation of raster. /// </summary> /// <param name="source">A System.Drawing.Bitmap instance containing the source image</param> /// <param name="sourceControlPoints">Control points of source</param> /// <param name="destinationControlPoints">Control points on the map</param> /// <param name="rectangle">A bounding rectangle defining a bouns of transformed raster</param> /// <param name="progress">Defines a method which is called to notify a subscriber about completion state.</param> /// <returns>A System.Drawing.Bitmap instance containing the transformed image</returns> public static Bitmap BindRaster(Bitmap source, Point[] sourceControlPoints, ICoordinate[] destinationControlPoints, out BoundingRectangle rectangle, RasterBindingProgress progress) { #if DEMO throw new NotImplementedException("This method is not implemented in demo version."); #else if (source == null) { throw new ArgumentNullException("source"); } if (sourceControlPoints.Length != destinationControlPoints.Length) { throw new ArgumentException("Number of control points of raster and map should be the same."); } if (sourceControlPoints.Length < 3) { throw new ArgumentException("Number of control points should not be less than 3"); } if (!checkControlPoints(source.Width, source.Height, sourceControlPoints)) { throw new ArgumentException("At least one source control point is outside raster", "sourceControlPoints"); } ICoordinate[,] warpTransformResult = new ICoordinate[source.Width, source.Height]; PointF[,] affinneTransformResult = new PointF[source.Width, source.Height]; // вычисляем результат аффинного преобразования примененного к координатам точек исходного растра calculateAffinneTransform(source.Width, source.Height, affinneTransformResult, sourceControlPoints, destinationControlPoints, progress); ICoordinate[] shifts = new ICoordinate[destinationControlPoints.Length]; for (int i = 0; i < shifts.Length; i++) { PointF p = affinneTransformResult[sourceControlPoints[i].X, sourceControlPoints[i].Y]; shifts[i] = PlanimetryEnvironment.NewCoordinate(destinationControlPoints[i].X - p.X, destinationControlPoints[i].Y - p.Y); } // вычисляем новые координаты точек исходного растра, полученные в результате "коробления" calculateRubberSheetTransform(source.Width, source.Height, affinneTransformResult, warpTransformResult, destinationControlPoints, shifts, progress); // вычисляем ограничивающий прямоугольник преобразованного растра rectangle = new BoundingRectangle(); for (int i = 0; i < source.Width; i++) { for (int j = 0; j < source.Height; j++) { if (!double.IsNaN(warpTransformResult[i, j].X) && !double.IsNaN(warpTransformResult[i, j].Y)) { rectangle.Join(warpTransformResult[i, j]); } } } return(calcDestRaster(source, rectangle, warpTransformResult, progress)); #endif }
private void internalInsertSegment(Segment segment, SegmentLabel tag) { segment = (Segment)segment.Clone(); _boundingRectangle.Join(segment.V1); _boundingRectangle.Join(segment.V2); if (_segments.Count > 0) { if (segment.V2.ExactEquals(_segments[0].V1)) { _segments.Insert(0, segment); _labels.Insert(0, tag); return; } } _segments.Add(segment); _labels.Add(tag); }
private BoundingRectangle getMinBoundingQuad(BoundingRectangle rectangle) { ICoordinate center = rectangle.Center(); double maxHalfSize = Math.Max(rectangle.Width, rectangle.Height) / 2; BoundingRectangle result = new BoundingRectangle(center.X - maxHalfSize, center.Y - maxHalfSize, center.X + maxHalfSize, center.Y + maxHalfSize); result.Join(rectangle); return(result); }
private void forceInsert(IIndexable obj) { _objects.Add(obj); if (_geometriesRectangle == null) { _geometriesRectangle = (BoundingRectangle)obj.BoundingRectangle.Clone(); } else { _geometriesRectangle.Join(obj.BoundingRectangle); } }
/// <summary> /// Transforms coordinates of the bounding rectangle. /// </summary> /// <param name="box">Rectangle to transform</param> /// <param name="transform">The transformation to apply</param> /// <returns>The transformed rectangle</returns> public static BoundingRectangle TransformBoundingRectangle(BoundingRectangle box, IMathTransform transform) { if (box == null) { return(null); } ICoordinate[] corners = new ICoordinate[4]; corners[0] = PlanimetryEnvironment.NewCoordinate(transform.Transform(box.Min.Values())); corners[1] = PlanimetryEnvironment.NewCoordinate(transform.Transform(box.Max.Values())); corners[2] = PlanimetryEnvironment.NewCoordinate(transform.Transform(PlanimetryEnvironment.NewCoordinate(box.MinX, box.MaxY).Values())); corners[3] = PlanimetryEnvironment.NewCoordinate(transform.Transform(PlanimetryEnvironment.NewCoordinate(box.MaxX, box.MinY).Values())); BoundingRectangle result = new BoundingRectangle(); for (int i = 0; i < 4; i++) { result.Join(corners[i]); } return(result); }
/// <summary> /// Performs a rubbersheeting transformation of raster. /// </summary> /// <param name="source">A System.Drawing.Bitmap instance containing the source image</param> /// <param name="sourceControlPoints">Control points of source</param> /// <param name="destinationControlPoints">Control points on the map</param> /// <param name="rectangle">A bounding rectangle defining a bouns of transformed raster</param> /// <param name="progress">Defines a method which is called to notify a subscriber about completion state.</param> /// <returns>A System.Drawing.Bitmap instance containing the transformed image</returns> public static Bitmap BindRaster(Bitmap source, Point[] sourceControlPoints, ICoordinate[] destinationControlPoints, out BoundingRectangle rectangle, RasterBindingProgress progress) { #if DEMO throw new NotImplementedException("This method is not implemented in demo version."); #else if (source == null) throw new ArgumentNullException("source"); if (sourceControlPoints.Length != destinationControlPoints.Length) throw new ArgumentException("Number of control points of raster and map should be the same."); if (sourceControlPoints.Length < 3) throw new ArgumentException("Number of control points should not be less than 3"); if (!checkControlPoints(source.Width, source.Height, sourceControlPoints)) throw new ArgumentException("At least one source control point is outside raster", "sourceControlPoints"); ICoordinate[,] warpTransformResult = new ICoordinate[source.Width, source.Height]; PointF[,] affinneTransformResult = new PointF[source.Width, source.Height]; // вычисляем результат аффинного преобразования примененного к координатам точек исходного растра calculateAffinneTransform(source.Width, source.Height, affinneTransformResult, sourceControlPoints, destinationControlPoints, progress); ICoordinate[] shifts = new ICoordinate[destinationControlPoints.Length]; for (int i = 0; i < shifts.Length; i++) { PointF p = affinneTransformResult[sourceControlPoints[i].X, sourceControlPoints[i].Y]; shifts[i] = PlanimetryEnvironment.NewCoordinate(destinationControlPoints[i].X - p.X, destinationControlPoints[i].Y - p.Y); } // вычисляем новые координаты точек исходного растра, полученные в результате "коробления" calculateRubberSheetTransform(source.Width, source.Height, affinneTransformResult, warpTransformResult, destinationControlPoints, shifts, progress); // вычисляем ограничивающий прямоугольник преобразованного растра rectangle = new BoundingRectangle(); for (int i = 0; i < source.Width; i++) for (int j = 0; j < source.Height; j++) { if (!double.IsNaN(warpTransformResult[i, j].X) && !double.IsNaN(warpTransformResult[i, j].Y)) rectangle.Join(warpTransformResult[i, j]); } return calcDestRaster(source, rectangle, warpTransformResult, progress); #endif }
/// <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> /// Transforms coordinates of the bounding rectangle. /// </summary> /// <param name="box">Rectangle to transform</param> /// <param name="transform">The transformation to apply</param> /// <returns>The transformed rectangle</returns> public static BoundingRectangle TransformBoundingRectangle(BoundingRectangle box, IMathTransform transform) { if (box == null) return null; ICoordinate[] corners = new ICoordinate[4]; corners[0] = PlanimetryEnvironment.NewCoordinate(transform.Transform(box.Min.Values())); corners[1] = PlanimetryEnvironment.NewCoordinate(transform.Transform(box.Max.Values())); corners[2] = PlanimetryEnvironment.NewCoordinate(transform.Transform(PlanimetryEnvironment.NewCoordinate(box.MinX, box.MaxY).Values())); corners[3] = PlanimetryEnvironment.NewCoordinate(transform.Transform(PlanimetryEnvironment.NewCoordinate(box.MaxX, box.MinY).Values())); BoundingRectangle result = new BoundingRectangle(); for (int i = 0; i < 4; i++) result.Join(corners[i]); return result; }
private void handleCircleEvent(FortuneCircleEvent ev) { FortuneArc ln = ev.Arc.LeftNeighbor; FortuneArc rn = ev.Arc.RightNeighbor; // remove events range associated with this arc if (ln.CircleEvent != null) { _eventList.Remove(ln.CircleEvent); } if (rn.CircleEvent != null) { _eventList.Remove(rn.CircleEvent); } // remove the arc of coastline _shoreLine.RemoveArc(ev.Arc); //fix slave nodes arc ribs if (ev.Arc.LeftNode != null) { ev.Arc.LeftNode.Point = ev.CircleCenter; ev.Arc.LeftNode.IsInfinit = false; } if (ev.Arc.RightNode != null) { ev.Arc.RightNode.Point = ev.CircleCenter; ev.Arc.RightNode.IsInfinit = false; } // add a new edge VoronoiEdge edge = new VoronoiEdge(ln.Site.Cell, rn.Site.Cell); edge.Node1 = new VoronoiNode(ev.CircleCenter.X, ev.CircleCenter.Y); edge.Node2 = new VoronoiNode((ln.Site.Cell.DataPoint.X + rn.Site.Cell.DataPoint.X) / 2, (ln.Site.Cell.DataPoint.Y + rn.Site.Cell.DataPoint.Y) / 2); //expand the bounding rectangle of the chart _rectangle.Join(ev.CircleCenter); // one node of the new edge is fixed, the second - no edge.Node1.IsInfinit = false; edge.Node2.IsInfinit = true; // dobavleyaem edge to cells ln.Site.Cell.AddEdge(edge); rn.Site.Cell.AddEdge(edge); //add a triangle in the Delaunay triangulation, if necessary if (_buildTriangles) { _triangles.Add(ev.Triangle); } // not a fixed node is a new edge now vanished neighbors arc ln.RightNode = edge.Node2; rn.LeftNode = edge.Node2; FortuneArc lnln = ln.LeftNeighbor; FortuneArc lnrn = ln.RightNeighbor; FortuneArc rnln = rn.LeftNeighbor; FortuneArc rnrn = rn.RightNeighbor; // add events to the newly formed circle arcs triples if (lnln != null) { if (lnrn != null) { FortuneEvent eventToAdd = getCircleEvent(lnln, ln, lnrn, ev.Point.Y); if (eventToAdd != null) { addCircleEvent(eventToAdd); } ln.CircleEvent = eventToAdd; } } if (rnln != null) { if (rnrn != null) { FortuneEvent eventToAdd = getCircleEvent(rnln, rn, rnrn, ev.Point.Y); if (eventToAdd != null) { addCircleEvent(eventToAdd); } rn.CircleEvent = eventToAdd; } } }
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; }
private void init() { _nodes.Clear(); _edges.Clear(); _sourceSegments.Clear(); int pointCount = 0; _sourceBounds = new BoundingRectangle(); if (_sourceGeometry1 != null) { _sourceBounds.Join(_sourceGeometry1.GetBoundingRectangle()); pointCount += _sourceGeometry1.CoordinateCount; } if (_sourceGeometry2 != null) { _sourceBounds.Join(_sourceGeometry2.GetBoundingRectangle()); pointCount += _sourceGeometry2.CoordinateCount; } if (pointCount > 800) { _sourceBounds.Grow(PlanimetryAlgorithms.Tolerance * 10); _splittedSegmentIndex = new KDTree(_sourceBounds); _splittedSegmentIndex.MaxDepth = 20; _splittedSegmentIndex.BoxSquareThreshold = _sourceBounds.Width * _sourceBounds.Height / 10000; } }
private void addFeaturesToCache(IFeatureReceiver fr, List<Feature> points, List<Feature> multiPoints, List<Feature> polylines, List<Feature> polygons) { _cacheAccessor.Key = fr.Alias; if (!_cacheAccessor.ExistsInCache) { BoundingRectangle b = new BoundingRectangle(); List<Feature> pts = new List<Feature>(); foreach (Feature feature in points) { b.Join(feature.BoundingRectangle); pts.Add(feature); } foreach (Feature feature in multiPoints) { b.Join(feature.BoundingRectangle); pts.Add(feature); } buildAndSaveIndex(MapAround.Mapping.FeatureType.Point, b, fr.DefaultPointsIndexSettings, pts); b = new BoundingRectangle(); foreach (Feature feature in polylines) b.Join(feature.BoundingRectangle); buildAndSaveIndex(MapAround.Mapping.FeatureType.Polyline, b, fr.DefaultPolylinesIndexSettings, polylines); b = new BoundingRectangle(); foreach (Feature feature in polygons) b.Join(feature.BoundingRectangle); buildAndSaveIndex(MapAround.Mapping.FeatureType.Polygon, b, fr.DefaultPolygonsIndexSettings, polygons); if (_processAttributes) _cacheAccessor.SaveAttributeNames(fr.FeatureAttributeNames); } }