public static void Run() { //ExStart: IterateOverGeometriesInGeometry Point pointGeometry = new Point(40.7128, -74.006); LineString lineGeometry = new LineString(); lineGeometry.AddPoint(78.65, -32.65); lineGeometry.AddPoint(-98.65, 12.65); GeometryCollection geometryCollection = new GeometryCollection(); geometryCollection.Add(pointGeometry); geometryCollection.Add(lineGeometry); foreach (Geometry geometry in geometryCollection) { switch (geometry.GeometryType) { case GeometryType.Point: Point point = (Point)geometry; break; case GeometryType.LineString: LineString line = (LineString)geometry; break; } } //ExEnd: IterateOverGeometriesInGeometry }
/// <summary> /// Применяет последовательность преобразований к коллекции линейных объектов. /// </summary> /// <param name="sourceGeometries">Коллекция линейных объектов</param> /// <returns>Коллекция преобразованных объектов</returns> public GeometryCollection GetLines(GeometryCollection sourceGeometries) { GeometryCollection tempSource = new GeometryCollection(); foreach (IGeometry g in sourceGeometries) { tempSource.Add(g); } GeometryCollection result = new GeometryCollection(); foreach (ILineTransformer transformer in _transformers) { result.Clear(); foreach (IGeometry g in tempSource) { if (g.CoordinateCount < 2) { continue; } GeometryCollection gc = null; if (g is LinePath) { gc = transformer.GetLines((LinePath)g); } else if (g is Contour) { gc = transformer.GetLines((Contour)g); } else { throw new ArgumentException("Source collection should contain only contours and linepaths.", "sourceGeometries"); } foreach (IGeometry g1 in gc) { if (!(g1 is LinePath || g1 is Contour)) { throw new InvalidOperationException("LineTransformation \"" + transformer.GetType().FullName + "\" has wrong output."); } result.Add(g1); } } tempSource.Clear(); foreach (IGeometry g in result) { tempSource.Add(g); } } return(result); }
/// <summary> /// Converts a collection of geometric shapes on the surface of the ellipsoid /// to the collection of geometric figures in the plane according to the given gnomonic projection. /// </summary> /// <param name="collection">Collection of geometric shapes on the surface of the ellipsoid</param> /// <param name="projection">Projection</param> /// <returns>Collection of geometric figures in the plane</returns> public static GeometryCollection GetGeometries(GeographyCollection collection, GnomonicProjection projection) { GeometryCollection result = new GeometryCollection(); IGeometry geometry = null; foreach (IGeography geography in collection) { if (geography is GeoPoint) { geometry = projectPoint((GeoPoint)geography, projection); } else if (geography is GeoPolyline) { geometry = projectPolyline((GeoPolyline)geography, projection); } else if (geography is GeoPolygon) { geometry = projectPolygon((GeoPolygon)geography, projection); } else if (geography is GeoMultiPoint) { geometry = projectMultiPoint((GeoMultiPoint)geography, projection); } else { throw new NotImplementedException("Geometry \"" + geography.GetType().FullName + "\" is not supported."); } result.Add(geometry); } return(result); }
/// <summary> /// Применяет последовательность преобразований к ломаной линии. /// </summary> /// <param name="path">Ломаная линия</param> /// <returns>Коллекция преобразованных объектов</returns> public GeometryCollection GetLines(LinePath path) { GeometryCollection gc = new GeometryCollection(); gc.Add(path); return(GetLines(gc)); }
public System.Windows.Media.Geometry GetTransformedGeometry(SceneView view, SceneElement element, System.Windows.Media.Geometry renderedGeometry, Matrix matrix) { if (Adorner.NonAffineTransformInParentStack(element)) { PathGeometry pathGeometry = renderedGeometry.GetFlattenedPathGeometry().Clone(); Transform transform = view.Artboard.CalculateTransformFromContentToArtboard(); foreach (PathFigure pathFigure in pathGeometry.Figures) { Point startPoint = pathFigure.StartPoint; Point point1 = view.TransformPoint(element.Visual, (IViewObject)view.HitTestRoot, startPoint); pathFigure.StartPoint = transform.Transform(point1); foreach (PathSegment pathSegment in pathFigure.Segments) { LineSegment lineSegment; if ((lineSegment = pathSegment as LineSegment) != null) { Point point2 = lineSegment.Point; Point point3 = view.TransformPoint(element.Visual, (IViewObject)view.HitTestRoot, point2); lineSegment.Point = transform.Transform(point3); } else { PolyLineSegment polyLineSegment; if ((polyLineSegment = pathSegment as PolyLineSegment) != null) { for (int index = 0; index < polyLineSegment.Points.Count; ++index) { Point point2 = polyLineSegment.Points[index]; Point point3 = view.TransformPoint(element.Visual, (IViewObject)view.HitTestRoot, point2); polyLineSegment.Points[index] = transform.Transform(point3); } } } } } return((System.Windows.Media.Geometry)pathGeometry); } Transform transform1 = renderedGeometry.Transform; if (transform1 != null) { matrix = transform1.Value * matrix; } MatrixTransform matrixTransform = new MatrixTransform(matrix); matrixTransform.Freeze(); if (renderedGeometry.IsFrozen) { GeometryCollection geometryCollection = new GeometryCollection(1); geometryCollection.Add(renderedGeometry); geometryCollection.Freeze(); renderedGeometry = (System.Windows.Media.Geometry) new GeometryGroup() { Children = geometryCollection }; } renderedGeometry.Transform = (Transform)matrixTransform; renderedGeometry.Freeze(); return(renderedGeometry); }
private void TestTree_OutsideIn(SpatialSubdivision tree, ICollection <Triangle> triList, int numRays = 100000) { var triSet = new GeometryCollection(); foreach (var tri in triList) { triSet.Add(tri); } for (var i = 1; i <= numRays; i++) { var start = MakeRandomVector(triangleSpaceSize * 10); var end = MakeRandomVector(triangleSpaceSize); var dir = end - start; var info = tree.IntersectRay(start, dir, context); var infoBase = triSet.IntersectRay(start, dir, context); Assert.AreEqual(infoBase == null, info == null, "Ray " + i + ": SpatialSubdivision and GeometryCollection differ in intersection status"); if (info != null) { Assert.AreEqual(infoBase.triIndex, info.triIndex, "triIndex diff on ray " + i); Assert.AreEqual(infoBase.rayFrac, info.rayFrac, 1e-10, "rayFrac diff on ray " + i); Assert.AreEqual(infoBase.pos, info.pos, "pos diff on ray " + i); Assert.AreEqual(infoBase.normal, info.normal, "normal diff on ray " + i); Assert.AreEqual(infoBase.color, info.color, "color diff on ray " + i); } } }
/// <summary> /// Применяет последовательность преобразований к контуру. /// </summary> /// <param name="contour">Контур</param> /// <returns>Коллекция преобразованных объектов</returns> public GeometryCollection GetLines(Contour contour) { GeometryCollection gc = new GeometryCollection(); gc.Add(contour); return(GetLines(gc)); }
public static void Run() { //ExStart: CreateGeometryCollection Point point = new Point(40.7128, -74.006); LineString line = new LineString(); line.AddPoint(78.65, -32.65); line.AddPoint(-98.65, 12.65); GeometryCollection geometryCollection = new GeometryCollection(); geometryCollection.Add(point); geometryCollection.Add(line); //ExEnd: CreateGeometryCollection }
public static GeometryGroup DarkModuleGeometry(BitMatrix matrix) { GeometryCollection gCollection = new GeometryCollection(); GeometryGroup gGroup = new GeometryGroup(); if (matrix == null) { gGroup.Children = gCollection; return(gGroup); } int preX = -1; int width = matrix.Width; for (int y = 0; y < width; y++) { for (int x = 0; x < width; x++) { if (matrix[x, y]) { //Set start point if preX == -1 if (preX == -1) { preX = x; } //If this is last module in that row. Draw rectangle if (x == width - 1) { gCollection.Add(CreateRectGeometry(new Rect(preX, y, x - preX + 1, 1))); preX = -1; } } else if (!matrix[x, y] && preX != -1) { //Here will be first light module after sequence of dark module. //Draw previews sequence of dark Module gCollection.Add(CreateRectGeometry(new Rect(preX, y, x - preX, 1))); preX = -1; } } } gGroup.Children = gCollection; return(gGroup); }
private static void ExtractGeometry(DrawingGroup group, GeometryCollection geomColl) { if (geomColl == null) { return; } DrawingCollection drawings = group.Children; int textItem = drawings.Count; for (int i = 0; i < textItem; i++) { Drawing drawing = drawings[i]; GeometryDrawing aDrawing = drawing as GeometryDrawing; if (aDrawing != null) { Geometry aGeometry = aDrawing.Geometry; if (aGeometry != null) { GeometryGroup geomGroup = aGeometry as GeometryGroup; if (geomGroup != null) { GeometryCollection children = geomGroup.Children; for (int j = 0; j < children.Count; j++) { geomColl.Add(children[j]); } } else { geomColl.Add(aGeometry); } } } else { DrawingGroup innerGroup = drawing as DrawingGroup; if (innerGroup != null) { ExtractGeometry(innerGroup, geomColl); } } } }
/// <summary> /// Access the java.awt.Shape outlines of each annotation adjunct. /// </summary> /// <returns>annotation outlines</returns> public GeometryCollection GetAnnotationOutlines() { var shapes = new GeometryCollection(); foreach (var adjunct in annotationAdjuncts) { shapes.Add(adjunct.GetOutline()); } return(shapes); }
private static IMultiGeometry FlattenMultiGeometry(IMultiGeometry mgeom, FgfGeometryFactory factory) { GeometryCollection geometries = new GeometryCollection(); for (int i = 0; i < mgeom.Count; i++) { geometries.Add(Flatten(mgeom[i], factory)); } return(factory.CreateMultiGeometry(geometries)); }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { StrokeCollection strokes = value as StrokeCollection; GeometryCollection gc = new GeometryCollection(); foreach (Stroke stroke in strokes) { Path path = StrokeToPath(stroke); gc.Add(path.Data); } return gc; }
public static void Run() { //ExStart: CountGeometriesInGeometry Point point = new Point(40.7128, -74.006); LineString line = new LineString(); line.AddPoint(78.65, -32.65); line.AddPoint(-98.65, 12.65); GeometryCollection geometryCollection = new GeometryCollection(); geometryCollection.Add(point); geometryCollection.Add(line); int geometriesCount = geometryCollection.Count; Console.WriteLine(geometriesCount); // 2 //ExEnd: CountGeometriesInGeometry }
public static GeometryGroup DarkModuleGeometry(BitMatrix matrix) { GeometryCollection gCollection = new GeometryCollection(); GeometryGroup gGroup = new GeometryGroup(); if (matrix == null) { gGroup.Children = gCollection; return gGroup; } int preX = -1; int width = matrix.Width; for (int y = 0; y < width; y++) { for (int x = 0; x < width; x++) { if (matrix[x, y]) { //Set start point if preX == -1 if (preX == -1) preX = x; //If this is last module in that row. Draw rectangle if (x == width - 1) { gCollection.Add(CreateRectGeometry(new Rect(preX, y, x - preX + 1, 1))); preX = -1; } } else if (!matrix[x, y] && preX != -1) { //Here will be first light module after sequence of dark module. //Draw previews sequence of dark Module gCollection.Add(CreateRectGeometry(new Rect(preX, y, x - preX, 1))); preX = -1; } } } gGroup.Children = gCollection; return gGroup; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { StrokeCollection strokes = value as StrokeCollection; GeometryCollection gc = new GeometryCollection(); foreach (Stroke stroke in strokes) { Path path = StrokeToPath(stroke); gc.Add(path.Data); } return(gc); }
public void Children_Change_Should_Raise_Changed() { var target = new GeometryGroup(); var children = new GeometryCollection(); target.Children = children; var isCalled = false; target.Changed += (s, e) => isCalled = true; children.Add(new StreamGeometry()); Assert.True(isCalled); }
public void RayIntersectTriangleCollectionFromInside_Performance() { #if DEBUG // my laptop in High Performance mode const double minMillionRaysPerSec = 4.5; const double maxMillionRaysPerSec = 5.0; #elif APPVEYOR_PERFORMANCE_MARGINS // AppVeyor build server const double minMillionRaysPerSec = 21.0; const double maxMillionRaysPerSec = 29.0; #else // my laptop in High Performance mode const double minMillionRaysPerSec = 15.5; const double maxMillionRaysPerSec = 16.5; #endif const int numTriangles = 1000; const int randomSeed = 12345; random = new Random(randomSeed); var triSet = new GeometryCollection(); foreach (var tri in MakeRandomTriangles(numTriangles)) { triSet.Add(tri); } const int numRays = 10000; var numRaysHit = 0; DateTime startTime = DateTime.Now; for (var i = 0; i < numRays; i++) { var start = MakeRandomVector(triangleSpaceSize); var dir = MakeRandomVector(-1, 1, -1, 1, -1, 1); var info = triSet.IntersectRay(start, dir, context); if (info != null) { numRaysHit++; } } var elapsedTime = DateTime.Now - startTime; Assert.IsTrue(numRays * 0.2 < numRaysHit && numRaysHit < numRays * 0.3, "Num rays hit {0} should be 20-30% of total rays {1}", numRaysHit, numRays); var millionRayTriPerSec = numRays / 1000000.0 / elapsedTime.TotalSeconds * numTriangles; Assert.IsTrue(minMillionRaysPerSec < millionRayTriPerSec && millionRayTriPerSec < maxMillionRaysPerSec, "Rays per second {0:f2} not between {1} and {2} (millions)", millionRayTriPerSec, minMillionRaysPerSec, maxMillionRaysPerSec); Console.WriteLine("Performance: {0} million ray/tri per second", millionRayTriPerSec); }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { GeometryCollection geoColl = new GeometryCollection(); var sourceCollection = value as ICollection <Location>; if (sourceCollection != null) { int size = int.Parse(parameter.ToString()); foreach (var node in sourceCollection) { var nodeCenter = new Point(node.X * size, node.Y * size); var geo = new EllipseGeometry(center: nodeCenter, radiusX: 2, radiusY: 2); geoColl.Add(geo); } } return(geoColl); }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { GeometryCollection geoColl = new GeometryCollection(); var sourceCollection = value as ICollection <Connection>; if (sourceCollection != null) { int size = int.Parse(parameter.ToString()); foreach (var arc in sourceCollection) { var originPoint = new Point(x: arc.OriginLocation.X * size, y: arc.OriginLocation.Y * size); var destinationPoint = new Point(x: arc.DestinationLocation.X * size, y: arc.DestinationLocation.Y * size); var geo = new LineGeometry(originPoint, destinationPoint); geoColl.Add(geo); } } return(geoColl); }
private static GeoPolygon getPointBuffer(GeoPoint point, double angleDistance, int pointsPerCircle) { if (angleDistance < 0) return new GeoPolygon(); GnomonicProjection projection = new GnomonicProjection(point.L, point.Phi); PointD planePoint = new PointD(0, 0); Polygon planePolygon = (Polygon)planePoint.Buffer(Math.Tan(angleDistance), pointsPerCircle, false); GeometryCollection geometryColllection = new GeometryCollection(); geometryColllection.Add(planePolygon); GeographyCollection gc = GeometrySpreader.GetGeographies(geometryColllection, projection); if(gc[0] is GeoPolygon) return (GeoPolygon)gc[0]; return new GeoPolygon(); }
private static GeometryCollection GetArcGeometry(Point center, double radius, double startAngle, double endAngle, int segments, bool clockwise = true) { var geometryCollection = new GeometryCollection(); double angleDifference = 0; if (clockwise) { if (endAngle <= startAngle) { endAngle += 360; } angleDifference = endAngle - startAngle; } else { if (startAngle <= endAngle) { startAngle += 360; } angleDifference = startAngle - endAngle; } for (int i = 0; i < segments; i++) { double segmentStartAgnle = (startAngle + i * angleDifference / segments) * Math.PI / 180.0; double segmentEndAngle = (startAngle + (i + 1) * angleDifference / segments) * Math.PI / 180.0; Point startPoint = center + new Vector(Math.Cos(segmentStartAgnle), Math.Sin(segmentStartAgnle)) * radius; Point endPoint = center + new Vector(Math.Cos(segmentEndAngle), Math.Sin(segmentEndAngle)) * radius; geometryCollection.Add(new LineGeometry(startPoint, endPoint)); } return(geometryCollection); }
private static GeoPolygon getPointBuffer(GeoPoint point, double angleDistance, int pointsPerCircle) { if (angleDistance < 0) { return(new GeoPolygon()); } GnomonicProjection projection = new GnomonicProjection(point.L, point.Phi); PointD planePoint = new PointD(0, 0); Polygon planePolygon = (Polygon)planePoint.Buffer(Math.Tan(angleDistance), pointsPerCircle, false); GeometryCollection geometryColllection = new GeometryCollection(); geometryColllection.Add(planePolygon); GeographyCollection gc = GeometrySpreader.GetGeographies(geometryColllection, projection); if (gc[0] is GeoPolygon) { return((GeoPolygon)gc[0]); } return(new GeoPolygon()); }
/// <summary> /// Computes a convex hull of the specified points. /// </summary> /// <param name="points">Enumerator of coordinates for which convex hull should be computed</param> /// <returns>A list containing a sequence of the convex hull points</returns> public static IList <GeoPoint> GetConvexHull(IEnumerable <GeoPoint> points) { GeographyCollection geographyCollection = new GeographyCollection(); foreach (GeoPoint p in points) { geographyCollection.Add(p); } GnomonicProjection projection = GeometrySpreader.GetProjection(geographyCollection); GeometryCollection geometryCollection = GeometrySpreader.GetGeometries(geographyCollection, projection); List <ICoordinate> list = new List <ICoordinate>(); foreach (IGeometry g in geometryCollection) { list.Add(((PointD)g).Coordinate); } IList <ICoordinate> planarResult = PlanimetryAlgorithms.GetConvexHull(list); geometryCollection.Clear(); foreach (ICoordinate p in planarResult) { geometryCollection.Add(new PointD(p)); } geographyCollection = GeometrySpreader.GetGeographies(geometryCollection, projection); List <GeoPoint> result = new List <GeoPoint>(); foreach (GeoPoint p in geographyCollection) { result.Add(p); } return(result); }
private static IMultiGeometry FlattenMultiGeometry(IMultiGeometry mgeom, FgfGeometryFactory factory) { GeometryCollection geometries = new GeometryCollection(); for (int i = 0; i < mgeom.Count; i++) { geometries.Add(Flatten(mgeom[i], factory)); } return factory.CreateMultiGeometry(geometries); }
public IGeometryCollection CreateGeometryCollection(IEnumerable<IGeometry> geometries) { GeometryCollection collection = new GeometryCollection(16); collection.Factory = this; foreach (Geometry geometry in geometries) { collection.Add(geometry.Clone()); } return collection; }
/// <summary> /// Преобразует ломаную линию в коллекцию линейных объектов. /// </summary> /// <param name="path">Ломаная линия</param> /// <returns>Коллекция линейных объектов (LinePath и Contour)</returns> public GeometryCollection GetLines(LinePath path) { GeometryCollection result = new GeometryCollection(); double length = path.Length(); double strokePatternLength = 0; foreach (double d in _strokes) { strokePatternLength += d; } double offset = _offset % strokePatternLength; double currentLength = offset; double traversedLength = 0; int segmentIndex = 0; int strokeIndex = 0; while (currentLength < length) { double strokeLength = _strokes[strokeIndex]; List <ICoordinate> strokePoints = getStrokePoints(path.Vertices, currentLength, strokeLength, ref segmentIndex, ref traversedLength); if (strokePoints.Count > 0) { LinePath lp = new LinePath(); foreach (ICoordinate p in strokePoints) { lp.Vertices.Add(p); } result.Add(lp); } currentLength += strokeLength; strokeIndex++; currentLength += _strokes[strokeIndex]; if (strokeIndex == _strokes.Length - 1) { strokeIndex = 0; } else { strokeIndex++; } } currentLength = offset; bool isSpace = true; for (int i = _strokes.Length - 1; i >= 0; i--) { double strokeLength = _strokes[i]; if (strokeLength > currentLength) { strokeLength = currentLength; } currentLength -= strokeLength; traversedLength = 0; segmentIndex = 0; if (!isSpace) { List <ICoordinate> strokePoints = getStrokePoints(path.Vertices, currentLength, strokeLength, ref segmentIndex, ref traversedLength); if (strokePoints.Count > 0) { LinePath lp = new LinePath(); foreach (ICoordinate p in strokePoints) { lp.Vertices.Add(p); } result.Add(lp); } } if (currentLength == 0) { break; } isSpace = !isSpace; } return(result); }
private static GeoPolygon getPolylineBuffer(GeoPolyline geoPolyline, double angleDistance, int pointsPerCircle, bool allowParallels) { geoPolyline = (GeoPolyline)geoPolyline.Clone(); double minAngle = Math.Sin(Math.Abs(angleDistance)) * Math.Sin(Math.PI / pointsPerCircle); geoPolyline.ReduceSegments(minAngle); geoPolyline.Densify(minAngle); GnomonicProjection projection; IGeometry geometry; projectGeography(geoPolyline, out projection, out geometry); Polyline planePolyline = (Polyline)geometry; GeographyCollection geographyCollection = new GeographyCollection(); Polygon temp = new Polygon(); List <Polygon> partialBuffers = new List <Polygon>(); ICollection <IGeometry> unionResult = null; int c = 0; foreach (GeoPath path in geoPolyline.Paths) { for (int i = 0; i < path.Vertices.Count - 1; i++) { GeoPoint p = path.Vertices[i]; GeoPolygon tempPolygon = getPointBuffer(p, angleDistance, pointsPerCircle); geographyCollection.Clear(); geographyCollection.Add(tempPolygon); GeometryCollection gc = GeometrySpreader.GetGeometries(geographyCollection, projection); if (gc[0] is Polygon) { unionResult = temp.Union((Polygon)gc[0]); } if (unionResult.Count > 0) { temp = (Polygon)((GeometryCollection)unionResult)[0]; } c++; if (c == 3) { partialBuffers.Add(temp); temp = new Polygon(); c = 0; } } } if (temp.CoordinateCount > 0) { partialBuffers.Add(temp); } Polygon planeBuffer = mergePartialBuffers(partialBuffers, allowParallels); GeometryCollection geometryCollection = new GeometryCollection(); geometryCollection.Add(planeBuffer); geographyCollection = GeometrySpreader.GetGeographies(geometryCollection, projection); foreach (IGeography g in geographyCollection) { if (g is GeoPolygon) { return((GeoPolygon)g); } } return(new GeoPolygon()); }
private GeometryCollection calculateOverlay(IGeometry geometry1, IGeometry geometry2, OverlayType operation, bool performSnapping) { GeometryCollection result = new GeometryCollection(); if (geometry1 == null && geometry2 == null) return result; if (geometry2 == null) { if (operation != OverlayType.Intersection) result.Add((IGeometry)geometry1.Clone()); return result; } if (geometry1 == null) { if (operation == OverlayType.Intersection || operation == OverlayType.Difference) return result; result.Add((IGeometry)geometry2.Clone()); return result; } // If the bounding rectangles do not intersect, the result of all operations can be obtained easily BoundingRectangle br1 = geometry1.GetBoundingRectangle(); BoundingRectangle br2 = geometry2.GetBoundingRectangle(); if(!br1.IsEmpty()) br1.Grow(PlanimetryAlgorithms.Tolerance); if (!br2.IsEmpty()) br2.Grow(PlanimetryAlgorithms.Tolerance); if (!br1.Intersects(br2)) return calculateNonIntersectedObjectsOverlay(geometry1, geometry2, operation, performSnapping); // easier to convert the point-to-multipoint to preserve generality if (geometry1 is PointD) { PointD p = (PointD)geometry1.Clone(); geometry1 = new MultiPoint(new ICoordinate[] { p.Coordinate }); } if (geometry2 is PointD) { PointD p = (PointD)geometry2.Clone(); geometry2 = new MultiPoint(new ICoordinate[] { p.Coordinate }); } int minDim = Math.Min((int)geometry1.Dimension, (int)geometry2.Dimension); int maxDim = Math.Max((int)geometry1.Dimension, (int)geometry2.Dimension); // overlay calculation points if (minDim == 0 && maxDim == 0) getPointPointOverlay((MultiPoint)geometry1, (MultiPoint)geometry2, operation, result); // calculation overlay polylines if (minDim == 1 && maxDim == 1) getPolylinePolylineOverlay((Polyline)geometry1, (Polyline)geometry2, operation, result, false); // calculation of polygon overlay if (minDim == 2 && maxDim == 2) getPolygonPolygonOverlay((Polygon)geometry1, (Polygon)geometry2, operation, result, false); // calculation overlay points and polylines if (minDim == 0 && maxDim == 1) { if (geometry1 is MultiPoint) getPointPolylineOverlay((MultiPoint)geometry1, (Polyline)geometry2, operation, result, false, false); else getPointPolylineOverlay((MultiPoint)geometry2, (Polyline)geometry1, operation, result, false, true); } // calculation point and polygon overlay if (minDim == 0 && maxDim == 2) { if (geometry1 is MultiPoint) getPointPolygonOverlay((MultiPoint)geometry1, (Polygon)geometry2, operation, result, false, false); else getPointPolygonOverlay((MultiPoint)geometry2, (Polygon)geometry1, operation, result, false, true); } // calculation overlay polylines and polygons if (minDim == 1 && maxDim == 2) { if (geometry1 is Polyline) getPolylinePolygonOverlay((Polyline)geometry1, (Polygon)geometry2, operation, result, false, false); else getPolylinePolygonOverlay((Polyline)geometry2, (Polygon)geometry1, operation, result, false, true); } return result; }
private void getPointPolygonOverlay(MultiPoint mp, Polygon polygon, OverlayType operation, GeometryCollection result, bool performSnapping, bool inverseArgs) { try { _geometry1 = mp; _geometry2 = polygon; bool isValid = true; try { init(performSnapping); PlanarGraph graph = PlanarGraph.Build(_geometry1, _geometry2); // duration test of the point inside the polygon to "collect" the original ground foreach (PlanarGraphEdge edge in graph.Edges) { edge.IsVisited = false; edge.Enabled = edge.Label.UsedByObject2; } Polygon pg = graph.BuildPolygon(inverseArgs, !inverseArgs); // classify edges and nodes foreach (PlanarGraphEdge edge in graph.Edges) { edge.IsVisited = false; switch (operation) { case OverlayType.Intersection: edge.Enabled = false; break; case OverlayType.Union: edge.Enabled = edge.Label.UsedByObject2; break; case OverlayType.Difference: edge.Enabled = inverseArgs ? edge.Label.UsedByObject2 : false; break; case OverlayType.SymmetricDifference: edge.Enabled = edge.Label.UsedByObject2; break; } } foreach (PlanarGraphNode node in graph.Nodes) { bool hasEnabledEdges = false; foreach (PlanarGraphEdge edge in node.IncidentEdges) if (edge.Enabled) { hasEnabledEdges = true; break; } if (hasEnabledEdges) node.Enabled = false; else { switch (operation) { case OverlayType.Intersection: node.Enabled = (pg.ContainsPoint(node.Point) && !node.Label.UsedByObject2) || (node.Label.UsedByObject2 && node.Label.UsedByObject1); break; case OverlayType.Union: node.Enabled = !pg.ContainsPoint(node.Point) && !node.Label.UsedByObject2; break; case OverlayType.Difference: node.Enabled = inverseArgs ? false : !pg.ContainsPoint(node.Point) && !node.Label.UsedByObject2; break; case OverlayType.SymmetricDifference: node.Enabled = !pg.ContainsPoint(node.Point) && !node.Label.UsedByObject2; break; } } } // build results: // point List<PointD> points = graph.BuildPoints(); foreach (PointD p in points) result.Add(p); // The landfill has been constructed to assess the position of the point. // But it must be added to the result only in the case of the calculation of association, // symmetric difference and the difference, which is a decrease. if (operation == OverlayType.Union || operation == OverlayType.SymmetricDifference || (operation == OverlayType.Difference && inverseArgs)) { if (pg.CoordinateCount > 0) result.Add(pg); } for (int i = 0; i < result.Count; i++) { IGeometry g = translateGeometry(result[i], _translationCenter.X, _translationCenter.Y); if (g is PointD) result[i] = g; } } catch (TopologyException) { if (!performSnapping) isValid = false; else throw new InvalidOperationException("Unable to complete operation correctly with this value of tolerance (PlanimertyAlgorithms.Tolerance)"); } if (isValid) return; else { // overlay has not been calculated. // it may be possible to calculate the overlay aligned to the grid getPointPolygonOverlay(mp, polygon, operation, result, true, inverseArgs); return; } } finally { _geometry1 = null; _geometry2 = null; } }
private GeometryCollection calculateNonIntersectedObjectsOverlay(IGeometry geometry1, IGeometry geometry2, OverlayType operation, bool performSnapping) { GeometryCollection result = new GeometryCollection(); // zero crossing if (operation == OverlayType.Intersection) return result; // difference is equal to the first object if (operation == OverlayType.Difference) { result.Add((IGeometry)geometry1.Clone()); return result; } // symmetric difference and the union concatenating try { if (geometry1 is Polygon && geometry2 is Polygon) { _polygon1Contours = SimplifyContours(((Polygon)geometry1).Contours); _polygon2Contours = SimplifyContours(((Polygon)geometry2).Contours); Polygon p = new Polygon(); foreach (Contour c in _polygon1Contours) p.Contours.Add(c); foreach (Contour c in _polygon2Contours) p.Contours.Add(c); result.Add(p); } else if (geometry1 is Polyline && geometry2 is Polyline) { Polyline p = new Polyline(); foreach (LinePath path in ((Polyline)geometry1).Paths) p.Paths.Add(path); foreach (LinePath path in ((Polyline)geometry2).Paths) p.Paths.Add(path); result.Add(p); } else { // If a figure is still a proving ground to normalize topology if (geometry1 is Polygon) { geometry1 = (IGeometry)((Polygon)geometry1).Clone(); ((Polygon)geometry1).Simplify(); } if (geometry2 is Polygon) { geometry2 = (IGeometry)((Polygon)geometry2).Clone(); ((Polygon)geometry2).Simplify(); } result.Add(geometry1); result.Add(geometry2); } return result; } finally { _polygon1Contours = null; _polygon2Contours = null; } }
/// <summary> /// Creates a <see cref="GeometryCollection"/> using the next token in the stream. /// </summary> /// <param name="tokenizer"> Tokenizer over a stream of text in Well-known Text /// format. The next tokens must form a GeometryCollection Text.</param> /// <returns> /// A <see cref="GeometryCollection"/> specified by the next token in the stream.</returns> private static GeometryCollection ReadGeometryCollectionText(WktStreamTokenizer tokenizer) { GeometryCollection geometries = new GeometryCollection(); string nextToken = GetNextEmptyOrOpener(tokenizer); if (nextToken.Equals("EMPTY")) return geometries; geometries.Add(ReadGeometryTaggedText(tokenizer)); nextToken = GetNextCloserOrComma(tokenizer); while (nextToken.Equals(",")) { geometries.Add(ReadGeometryTaggedText(tokenizer)); nextToken = GetNextCloserOrComma(tokenizer); } return geometries; }
/// <summary> /// Interprets an OSM-object and returns the corresponding geometry. /// </summary> /// <param name="osmObject"></param> /// <returns></returns> public override GeometryCollection Interpret(CompleteOsmGeo osmObject) { // DISCLAIMER: this is a very very very simple geometry interpreter and // contains hardcoded all relevant tags. GeometryCollection collection = new GeometryCollection(); TagsCollectionBase tags; if (osmObject != null) { switch (osmObject.Type) { case CompleteOsmType.Node: TagsCollection newCollection = new TagsCollection( osmObject.Tags); newCollection.RemoveKey("FIXME"); newCollection.RemoveKey("node"); newCollection.RemoveKey("source"); if (newCollection.Count > 0) { // there is still some relevant information left. collection.Add(new Point((osmObject as CompleteNode).Coordinate)); } break; case CompleteOsmType.Way: tags = osmObject.Tags; bool isArea = false; if ((tags.ContainsKey("building") && !tags.IsFalse("building")) || (tags.ContainsKey("landuse") && !tags.IsFalse("landuse")) || (tags.ContainsKey("amenity") && !tags.IsFalse("amenity")) || (tags.ContainsKey("harbour") && !tags.IsFalse("harbour")) || (tags.ContainsKey("historic") && !tags.IsFalse("historic")) || (tags.ContainsKey("leisure") && !tags.IsFalse("leisure")) || (tags.ContainsKey("man_made") && !tags.IsFalse("man_made")) || (tags.ContainsKey("military") && !tags.IsFalse("military")) || (tags.ContainsKey("natural") && !tags.IsFalse("natural")) || (tags.ContainsKey("office") && !tags.IsFalse("office")) || (tags.ContainsKey("place") && !tags.IsFalse("place")) || (tags.ContainsKey("power") && !tags.IsFalse("power")) || (tags.ContainsKey("public_transport") && !tags.IsFalse("public_transport")) || (tags.ContainsKey("shop") && !tags.IsFalse("shop")) || (tags.ContainsKey("sport") && !tags.IsFalse("sport")) || (tags.ContainsKey("tourism") && !tags.IsFalse("tourism")) || (tags.ContainsKey("waterway") && !tags.IsFalse("waterway")) || (tags.ContainsKey("wetland") && !tags.IsFalse("wetland")) || (tags.ContainsKey("water") && !tags.IsFalse("water")) || (tags.ContainsKey("aeroway") && !tags.IsFalse("aeroway"))) { // these tags usually indicate an area. isArea = true; } if (tags.IsTrue("area")) { // explicitly indicated that this is an area. isArea = true; } else if (tags.IsFalse("area")) { // explicitly indicated that this is not an area. isArea = false; } if (isArea) { // area tags leads to simple polygon LineairRing lineairRing = new LineairRing((osmObject as CompleteWay).GetCoordinates().ToArray <GeoCoordinate>()); lineairRing.Attributes = new SimpleGeometryAttributeCollection(tags); collection.Add(lineairRing); } else { // no area tag leads to just a line. LineString lineString = new LineString((osmObject as CompleteWay).GetCoordinates().ToArray <GeoCoordinate>()); lineString.Attributes = new SimpleGeometryAttributeCollection(tags); collection.Add(lineString); } break; case CompleteOsmType.Relation: CompleteRelation relation = (osmObject as CompleteRelation); tags = relation.Tags; string typeValue; if (tags.TryGetValue("type", out typeValue)) { // there is a type in this relation. if (typeValue == "multipolygon") { // this relation is a multipolygon. Geometry geometry = this.InterpretMultipolygonRelation(relation); if (geometry != null) { // add the geometry. collection.Add(geometry); } } else if (typeValue == "boundary") { // this relation is a boundary. } } break; } } return(collection); }
private GeometryCollection CreateClippingRegion(SvgClipPathElement clipPath, WpfDrawingContext context) { GeometryCollection geomColl = new GeometryCollection(); foreach (XmlNode node in clipPath.ChildNodes) { if (node.NodeType != XmlNodeType.Element) { continue; } // Handle a case where the clip element has "use" element as a child... if (String.Equals(node.LocalName, "use")) { SvgUseElement useElement = (SvgUseElement)node; XmlElement refEl = useElement.ReferencedElement; if (refEl != null) { XmlElement refElParent = (XmlElement)refEl.ParentNode; useElement.OwnerDocument.Static = true; useElement.CopyToReferencedElement(refEl); refElParent.RemoveChild(refEl); useElement.AppendChild(refEl); foreach (XmlNode useChild in useElement.ChildNodes) { if (useChild.NodeType != XmlNodeType.Element) { continue; } SvgStyleableElement element = useChild as SvgStyleableElement; if (element != null && element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = CreateGeometry(element, context.OptimizePath); if (childPath != null) { geomColl.Add(childPath); } } } useElement.RemoveChild(refEl); useElement.RestoreReferencedElement(refEl); refElParent.AppendChild(refEl); useElement.OwnerDocument.Static = false; } } else { SvgStyleableElement element = node as SvgStyleableElement; if (element != null) { if (element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = CreateGeometry(element, context.OptimizePath); if (childPath != null) { geomColl.Add(childPath); } } else if (element.RenderingHint == SvgRenderingHint.Text) { GeometryCollection textGeomColl = GetTextClippingRegion(element, context); if (textGeomColl != null) { for (int i = 0; i < textGeomColl.Count; i++) { geomColl.Add(textGeomColl[i]); } } } } } } return geomColl; }
private static void ExtractGeometry(DrawingGroup group, GeometryCollection geomColl) { if (geomColl == null) { return; } DrawingCollection drawings = group.Children; int textItem = drawings.Count; for (int i = 0; i < textItem; i++) { Drawing drawing = drawings[i]; GeometryDrawing aDrawing = drawing as GeometryDrawing; if (aDrawing != null) { Geometry aGeometry = aDrawing.Geometry; if (aGeometry != null) { GeometryGroup geomGroup = aGeometry as GeometryGroup; if (geomGroup != null) { GeometryCollection children = geomGroup.Children; for (int j = 0; j < children.Count; j++) { geomColl.Add(children[j]); } } else { geomColl.Add(aGeometry); } } } else { DrawingGroup innerGroup = drawing as DrawingGroup; if (innerGroup != null) { ExtractGeometry(innerGroup, geomColl); } } } }
/// <summary> /// Применяет последовательность преобразований к контуру. /// </summary> /// <param name="contour">Контур</param> /// <returns>Коллекция преобразованных объектов</returns> public GeometryCollection GetLines(Contour contour) { GeometryCollection gc = new GeometryCollection(); gc.Add(contour); return GetLines(gc); }
/// <summary> /// Применяет последовательность преобразований к ломаной линии. /// </summary> /// <param name="path">Ломаная линия</param> /// <returns>Коллекция преобразованных объектов</returns> public GeometryCollection GetLines(LinePath path) { GeometryCollection gc = new GeometryCollection(); gc.Add(path); return GetLines(gc); }
/// <summary> /// Converts a collection of geometric shapes on the surface of the ellipsoid /// to the collection of geometric figures in the plane according to the given gnomonic projection. /// </summary> /// <param name="collection">Collection of geometric shapes on the surface of the ellipsoid</param> /// <param name="projection">Projection</param> /// <returns>Collection of geometric figures in the plane</returns> public static GeometryCollection GetGeometries(GeographyCollection collection, GnomonicProjection projection) { GeometryCollection result = new GeometryCollection(); IGeometry geometry = null; foreach (IGeography geography in collection) { if (geography is GeoPoint) { geometry = projectPoint((GeoPoint)geography, projection); } else if (geography is GeoPolyline) { geometry = projectPolyline((GeoPolyline)geography, projection); } else if (geography is GeoPolygon) { geometry = projectPolygon((GeoPolygon)geography, projection); } else if (geography is GeoMultiPoint) { geometry = projectMultiPoint((GeoMultiPoint)geography, projection); } else throw new NotImplementedException("Geometry \"" + geography.GetType().FullName + "\" is not supported."); result.Add(geometry); } return result; }
public Path ScalePath(IEnumerable <int> values, double width, double height) { int offScaleLine = 1; int offScalePoint = 5; int offScaleLabel = 8; double textHeight = 0; // Высота метки шкалы в пихелях GeometryCollection geoData = new GeometryCollection(); #region -> Scale Draw { LineGeometry sLine = new LineGeometry() { StartPoint = NormalizedPoint(XMax, YMin, width, height, offScaleLine), EndPoint = NormalizedPoint(XMax, YMax, width, height, offScaleLine) }; geoData.Add(sLine); foreach (int val in values) { LineGeometry sp = new LineGeometry() { StartPoint = NormalizedPoint(XMax, val, width, height, offScaleLine), EndPoint = NormalizedPoint(XMax, val, width, height, offScalePoint) }; FormattedText fText = new FormattedText(val.ToStringUI(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, FontFace, 8, Brushes.Black, PixelsPerDip); textHeight = fText.Height; // Запомним высоту метки шкалы в пихелях Geometry sl = fText.BuildGeometry(NormalizedPoint( XMax, val, width, height, offScaleLabel, 5)); geoData.Add(sp); geoData.Add(sl); } } #endregion #region -> Grid Draw if (YAmp > 1) { /// У нас шрифт высотой 8 пихелей. /// Пусть сетка шкалы будет не чаще 20 пихелей. /// double h = height - OffUp - OffDn; // Высота картинки в пихелях double nStep = h / textHeight / 3; // Первое приближение количества шагов шкалы, позволяющее избежать слипания меток int szStep = nStep == 0 ? 0 : ((int)(YAmp / nStep)); if (szStep > 1000) { szStep = 1000; } else if (szStep > 100) { szStep = 100; } else if (szStep > 50) { szStep = 50; } else if (szStep > 20) { szStep = 20; } else if (szStep > 10) { szStep = 10; } else if (szStep > 5) { szStep = 5; } else if (szStep > 2) { szStep = 2; } else { szStep = 1; // Не нашлось ограничений - на каждый рубль цены } // Получим нормализованные границы гридов int pMax = (int)((YMax / szStep) * szStep) - szStep; int pMin = (int)((YMin / szStep) * szStep) + szStep; for (int y = pMin; y <= pMax; y += szStep) { LineGeometry sLine = new LineGeometry() { StartPoint = NormalizedPoint(XMin, y, width, height), EndPoint = NormalizedPoint(XMax, y, width, height, offScalePoint), }; FormattedText fText = new FormattedText(y.ToStringUI(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, FontFace, 8, Brushes.Black, PixelsPerDip); textHeight = fText.Height; // Запомним высоту метки шкалы в пихелях Geometry sLabel = fText.BuildGeometry(NormalizedPoint( XMax, y, width, height, offScaleLabel, 5)); geoData.Add(sLine); geoData.Add(sLabel); } } #endregion geoData.SetValue(RenderOptions.EdgeModeProperty, EdgeMode.Aliased); Path p = new Path() { StrokeThickness = 0.25, UseLayoutRounding = false, SnapsToDevicePixels = true, Fill = new SolidColorBrush(Colors.White), Stroke = new SolidColorBrush(Colors.Black), Data = new GeometryGroup { Children = geoData } }; return(p); }
/// <summary> /// Draw the hatches and the transparent area where isn't covering the elements. /// </summary> /// <param name="drawingContext"></param> private void DrawBackgound(DrawingContext drawingContext) { PathGeometry hatchGeometry = null; Geometry rectGeometry = null; int count = _elementsBounds.Count; if ( count != 0 ) { // Create a union collection of the element regions. for ( int i = 0; i < count; i++ ) { Rect hatchRect = _elementsBounds[i]; if ( hatchRect.IsEmpty ) { continue; } hatchRect.Inflate(HatchBorderMargin / 2, HatchBorderMargin / 2); if ( hatchGeometry == null ) { PathFigure path = new PathFigure(); path.StartPoint = new Point(hatchRect.Left, hatchRect.Top); PathSegmentCollection segments = new PathSegmentCollection(); PathSegment line = new LineSegment(new Point(hatchRect.Right, hatchRect.Top), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Right, hatchRect.Bottom), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Left, hatchRect.Bottom), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Left, hatchRect.Top), true); line.Freeze(); segments.Add(line); segments.Freeze(); path.Segments = segments; path.IsClosed = true; path.Freeze(); hatchGeometry = new PathGeometry(); hatchGeometry.Figures.Add(path); } else { rectGeometry = new RectangleGeometry(hatchRect); rectGeometry.Freeze(); hatchGeometry = Geometry.Combine(hatchGeometry, rectGeometry, GeometryCombineMode.Union, null); } } } // Then, create a region which equals to "SelectionFrame - element1 bounds - element2 bounds - ..." GeometryGroup backgroundGeometry = new GeometryGroup( ); GeometryCollection geometryCollection = new GeometryCollection(); // Add the entile rectanlge to the group. rectGeometry = new RectangleGeometry(new Rect(0, 0, RenderSize.Width, RenderSize.Height)); rectGeometry.Freeze(); geometryCollection.Add(rectGeometry); // Add the union of the element rectangles. Then the group will do oddeven operation. Geometry outlineGeometry = null; if ( hatchGeometry != null ) { hatchGeometry.Freeze(); outlineGeometry = hatchGeometry.GetOutlinedPathGeometry(); outlineGeometry.Freeze(); if ( count == 1 && ((InkCanvasInnerCanvas)AdornedElement).InkCanvas.GetSelectedStrokes().Count == 0 ) { geometryCollection.Add(outlineGeometry); } } geometryCollection.Freeze(); backgroundGeometry.Children = geometryCollection; backgroundGeometry.Freeze(); // Then, draw the region which may contain holes so that the elements cannot be covered. // After that, the underneath elements can receive the messages. #if DEBUG_OUTPUT // Draw the debug feedback drawingContext.DrawGeometry(new SolidColorBrush(Color.FromArgb(128, 255, 255, 0)), null, backgroundGeometry); #else drawingContext.DrawGeometry(Brushes.Transparent, null, backgroundGeometry); #endif // At last, draw the hatch borders if ( outlineGeometry != null ) { drawingContext.DrawGeometry(null, _hatchPen, outlineGeometry); } }
/// <summary> /// Draw the hatches and the transparent area where isn't covering the elements. /// </summary> /// <param name="drawingContext"></param> private void DrawBackgound(DrawingContext drawingContext) { PathGeometry hatchGeometry = null; Geometry rectGeometry = null; int count = _elementsBounds.Count; if (count != 0) { // Create a union collection of the element regions. for (int i = 0; i < count; i++) { Rect hatchRect = _elementsBounds[i]; if (hatchRect.IsEmpty) { continue; } hatchRect.Inflate(HatchBorderMargin / 2, HatchBorderMargin / 2); if (hatchGeometry == null) { PathFigure path = new PathFigure(); path.StartPoint = new Point(hatchRect.Left, hatchRect.Top); PathSegmentCollection segments = new PathSegmentCollection(); PathSegment line = new LineSegment(new Point(hatchRect.Right, hatchRect.Top), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Right, hatchRect.Bottom), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Left, hatchRect.Bottom), true); line.Freeze(); segments.Add(line); line = new LineSegment(new Point(hatchRect.Left, hatchRect.Top), true); line.Freeze(); segments.Add(line); segments.Freeze(); path.Segments = segments; path.IsClosed = true; path.Freeze(); hatchGeometry = new PathGeometry(); hatchGeometry.Figures.Add(path); } else { rectGeometry = new RectangleGeometry(hatchRect); rectGeometry.Freeze(); hatchGeometry = Geometry.Combine(hatchGeometry, rectGeometry, GeometryCombineMode.Union, null); } } } // Then, create a region which equals to "SelectionFrame - element1 bounds - element2 bounds - ..." GeometryGroup backgroundGeometry = new GeometryGroup(); GeometryCollection geometryCollection = new GeometryCollection(); // Add the entile rectanlge to the group. rectGeometry = new RectangleGeometry(new Rect(0, 0, RenderSize.Width, RenderSize.Height)); rectGeometry.Freeze(); geometryCollection.Add(rectGeometry); // Add the union of the element rectangles. Then the group will do oddeven operation. Geometry outlineGeometry = null; if (hatchGeometry != null) { hatchGeometry.Freeze(); outlineGeometry = hatchGeometry.GetOutlinedPathGeometry(); outlineGeometry.Freeze(); if (count == 1 && ((InkCanvasInnerCanvas)AdornedElement).InkCanvas.GetSelectedStrokes().Count == 0) { geometryCollection.Add(outlineGeometry); } } geometryCollection.Freeze(); backgroundGeometry.Children = geometryCollection; backgroundGeometry.Freeze(); // Then, draw the region which may contain holes so that the elements cannot be covered. // After that, the underneath elements can receive the messages. #if DEBUG_OUTPUT // Draw the debug feedback drawingContext.DrawGeometry(new SolidColorBrush(Color.FromArgb(128, 255, 255, 0)), null, backgroundGeometry); #else drawingContext.DrawGeometry(Brushes.Transparent, null, backgroundGeometry); #endif // At last, draw the hatch borders if (outlineGeometry != null) { drawingContext.DrawGeometry(null, _hatchPen, outlineGeometry); } }
private void getPointPolylineOverlay(MultiPoint mp, Polyline polyline, OverlayType operation, GeometryCollection result, bool performSnapping, bool inverseArgs) { try { _geometry1 = mp; _geometry2 = polyline; bool isValid = true; try { init(performSnapping); PlanarGraph graph = PlanarGraph.Build(_geometry1, _geometry2); // classify edges and nodes foreach (PlanarGraphEdge edge in graph.Edges) { edge.IsVisited = false; switch (operation) { case OverlayType.Intersection: edge.Enabled = false; break; case OverlayType.Union: edge.Enabled = edge.Label.UsedByObject2; break; case OverlayType.Difference: edge.Enabled = inverseArgs ? edge.Label.UsedByObject2 : false; break; case OverlayType.SymmetricDifference: edge.Enabled = edge.Label.UsedByObject2; break; } } foreach (PlanarGraphNode node in graph.Nodes) { bool hasEnabledEdges = false; foreach (PlanarGraphEdge edge in node.IncidentEdges) if (edge.Enabled) { hasEnabledEdges = true; break; } if (hasEnabledEdges) node.Enabled = false; else { switch (operation) { case OverlayType.Intersection: node.Enabled = node.Label.UsedByObject1 && node.Label.UsedByObject2; break; case OverlayType.Union: node.Enabled = node.Label.UsedByObject1; break; case OverlayType.Difference: node.Enabled = inverseArgs ? false : !node.Label.UsedByObject2; break; case OverlayType.SymmetricDifference: node.Enabled = true; break; } } } // build results: // point List<PointD> points = graph.BuildPoints(); foreach (PointD p in points) result.Add(p); // polyline Polyline pl = graph.BuildPolyline(false, false); if (pl.CoordinateCount > 0) result.Add(pl); for (int i = 0; i < result.Count; i++) { IGeometry g = translateGeometry(result[i], _translationCenter.X, _translationCenter.Y); if (g is PointD) result[i] = g; } } catch (TopologyException) { if (!performSnapping) isValid = false; else throw new InvalidOperationException("Unable to complete operation correctly with this value of tolerance (PlanimertyAlgorithms.Tolerance)"); } if (isValid) return; else { // overlay has not been calculated. // it may be possible to calculate the overlay aligned to the grid getPointPolylineOverlay(mp, polyline, operation, result, true, inverseArgs); return; } } finally { _geometry1 = null; _geometry2 = null; } }
private void AggregateChildren(SvgAElement aElement, WpfDrawingContext context, float opacity) { _isAggregated = false; if (aElement == null || aElement.ChildNodes == null) { return; } string aggregatedFill = aElement.GetAttribute("fill"); bool isFillFound = !String.IsNullOrEmpty(aggregatedFill); SvgStyleableElement paintElement = null; if (isFillFound) { paintElement = aElement; } XmlNode targetNode = aElement; // Check if the children of the link are wrapped in a Group Element... if (aElement.ChildNodes.Count == 1) { SvgGElement groupElement = aElement.ChildNodes[0] as SvgGElement; if (groupElement != null) { targetNode = groupElement; } } WpfDrawingSettings settings = context.Settings; GeometryCollection geomColl = new GeometryCollection(); foreach (XmlNode node in targetNode.ChildNodes) { if (node.NodeType != XmlNodeType.Element) { continue; } // Handle a case where the clip element has "use" element as a child... if (String.Equals(node.LocalName, "use")) { SvgUseElement useElement = (SvgUseElement)node; XmlElement refEl = useElement.ReferencedElement; if (refEl != null) { XmlElement refElParent = (XmlElement)refEl.ParentNode; useElement.OwnerDocument.Static = true; useElement.CopyToReferencedElement(refEl); refElParent.RemoveChild(refEl); useElement.AppendChild(refEl); foreach (XmlNode useChild in useElement.ChildNodes) { if (useChild.NodeType != XmlNodeType.Element) { continue; } SvgStyleableElement element = useChild as SvgStyleableElement; if (element != null && element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = WpfRendering.CreateGeometry(element, settings.OptimizePath); if (childPath != null) { if (isFillFound) { string elementFill = element.GetAttribute("fill"); if (!String.IsNullOrEmpty(elementFill) && !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase)) { return; } } else { aggregatedFill = element.GetAttribute("fill"); isFillFound = !String.IsNullOrEmpty(aggregatedFill); if (isFillFound) { paintElement = element; } } geomColl.Add(childPath); } } } useElement.RemoveChild(refEl); useElement.RestoreReferencedElement(refEl); refElParent.AppendChild(refEl); useElement.OwnerDocument.Static = false; } } //else if (String.Equals(node.LocalName, "g")) //{ //} else { SvgStyleableElement element = node as SvgStyleableElement; if (element != null && element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = WpfRendering.CreateGeometry(element, settings.OptimizePath); if (childPath != null) { if (isFillFound) { string elementFill = element.GetAttribute("fill"); if (!String.IsNullOrEmpty(elementFill) && !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase)) { return; } } else { aggregatedFill = element.GetAttribute("fill"); isFillFound = !String.IsNullOrEmpty(aggregatedFill); if (isFillFound) { paintElement = element; } } geomColl.Add(childPath); } } } } if (geomColl.Count == 0 || paintElement == null) { return; } _aggregatedFill = paintElement; _aggregatedGeom = geomColl; _isAggregated = true; }
private void getPolylinePolygonOverlay(Polyline polyline, Polygon polygon, OverlayType operation, GeometryCollection result, bool performSnapping, bool inverseArgs) { try { _geometry1 = polyline; _geometry2 = polygon; bool isValid = true; try { init(performSnapping); PlanarGraph graph = PlanarGraph.Build(_geometry1, _geometry2); //building polygon foreach (PlanarGraphNode node in graph.Nodes) node.Layout = PlanarGraphNode.NodeLayout.Unknown; foreach (PlanarGraphEdge edge in graph.Edges) { edge.IsVisited = false; edge.Enabled = edge.Label.UsedByObject2; } Polygon pg = graph.BuildPolygon(true, false); // build results: // point foreach (PlanarGraphNode node in graph.Nodes) node.Enabled = isNodeEnabled(node, operation, polyline, pg, inverseArgs); List<PointD> points = graph.BuildPoints(); foreach (PointD p in points) result.Add(p); // polyline foreach (PlanarGraphEdge edge in graph.Edges) { edge.IsVisited = false; edge.Enabled = isLinearEdgeEnabled(edge, operation, pg, inverseArgs); } Polyline pl = graph.BuildPolyline(false, false); if (pl.CoordinateCount > 0) result.Add(pl); // landfill has been constructed, it may be added to the result if (operation == OverlayType.SymmetricDifference || operation == OverlayType.Union || (operation == OverlayType.Difference && inverseArgs)) if(pg.CoordinateCount > 0) result.Add(pg); for (int i = 0; i < result.Count; i++) { IGeometry g = translateGeometry(result[i], _translationCenter.X, _translationCenter.Y); if (g is PointD) result[i] = g; } } catch (TopologyException) { if (!performSnapping) isValid = false; else throw new InvalidOperationException("Unable to complete operation correctly with this value of tolerance (PlanimertyAlgorithms.Tolerance)"); } if (isValid) return; else { //overlay has not been calculated. // it may be possible to calculate the overlay aligned to the grid getPolylinePolygonOverlay(polyline, polygon, operation, result, true, inverseArgs); return; } } finally { _geometry1 = null; _geometry2 = null; } }
private GeometryCollection CreateClippingRegion(SvgClipPathElement clipPath, WpfDrawingContext context) { GeometryCollection geomColl = new GeometryCollection(); foreach (XmlNode node in clipPath.ChildNodes) { if (node.NodeType != XmlNodeType.Element) { continue; } // Handle a case where the clip element has "use" element as a child... if (string.Equals(node.LocalName, "use")) { SvgUseElement useElement = (SvgUseElement)node; XmlElement refEl = useElement.ReferencedElement; if (refEl != null) { XmlElement refElParent = (XmlElement)refEl.ParentNode; useElement.OwnerDocument.Static = true; useElement.CopyToReferencedElement(refEl); refElParent.RemoveChild(refEl); useElement.AppendChild(refEl); foreach (XmlNode useChild in useElement.ChildNodes) { if (useChild.NodeType != XmlNodeType.Element) { continue; } SvgStyleableElement element = useChild as SvgStyleableElement; if (element != null && element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = CreateGeometry(element, context.OptimizePath); if (childPath != null) { geomColl.Add(childPath); } } } useElement.RemoveChild(refEl); useElement.RestoreReferencedElement(refEl); refElParent.AppendChild(refEl); useElement.OwnerDocument.Static = false; } } else { SvgStyleableElement element = node as SvgStyleableElement; if (element != null) { if (element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = CreateGeometry(element, context.OptimizePath); if (childPath != null) { geomColl.Add(childPath); } } else if (element.RenderingHint == SvgRenderingHint.Text) { GeometryCollection textGeomColl = GetTextClippingRegion(element, context); if (textGeomColl != null) { for (int i = 0; i < textGeomColl.Count; i++) { geomColl.Add(textGeomColl[i]); } } } } } } return(geomColl); }
/// <summary> /// Interprets an OSM-object and returns the corresponding geometry. /// </summary> /// <param name="osmObject"></param> /// <returns></returns> public override GeometryCollection Interpret(CompleteOsmGeo osmObject) { // DISCLAIMER: this is a very very very simple geometry interpreter and // contains hardcoded all relevant tags. GeometryCollection collection = new GeometryCollection(); TagsCollectionBase tags; if (osmObject != null) { switch (osmObject.Type) { case CompleteOsmType.Node: TagsCollection newCollection = new TagsCollection( osmObject.Tags); newCollection.RemoveKey("FIXME"); newCollection.RemoveKey("node"); newCollection.RemoveKey("source"); if (newCollection.Count > 0) { // there is still some relevant information left. collection.Add(new Point((osmObject as CompleteNode).Coordinate)); } break; case CompleteOsmType.Way: tags = osmObject.Tags; bool isArea = false; if ((tags.ContainsKey("building") && !tags.IsFalse("building")) || (tags.ContainsKey("landuse") && !tags.IsFalse("landuse")) || (tags.ContainsKey("amenity") && !tags.IsFalse("amenity")) || (tags.ContainsKey("harbour") && !tags.IsFalse("harbour")) || (tags.ContainsKey("historic") && !tags.IsFalse("historic")) || (tags.ContainsKey("leisure") && !tags.IsFalse("leisure")) || (tags.ContainsKey("man_made") && !tags.IsFalse("man_made")) || (tags.ContainsKey("military") && !tags.IsFalse("military")) || (tags.ContainsKey("natural") && !tags.IsFalse("natural")) || (tags.ContainsKey("office") && !tags.IsFalse("office")) || (tags.ContainsKey("place") && !tags.IsFalse("place")) || (tags.ContainsKey("power") && !tags.IsFalse("power")) || (tags.ContainsKey("public_transport") && !tags.IsFalse("public_transport")) || (tags.ContainsKey("shop") && !tags.IsFalse("shop")) || (tags.ContainsKey("sport") && !tags.IsFalse("sport")) || (tags.ContainsKey("tourism") && !tags.IsFalse("tourism")) || (tags.ContainsKey("waterway") && !tags.IsFalse("waterway")) || (tags.ContainsKey("wetland") && !tags.IsFalse("wetland")) || (tags.ContainsKey("water") && !tags.IsFalse("water")) || (tags.ContainsKey("aeroway") && !tags.IsFalse("aeroway"))) { // these tags usually indicate an area. isArea = true; } if (tags.IsTrue("area")) { // explicitly indicated that this is an area. isArea = true; } else if (tags.IsFalse("area")) { // explicitly indicated that this is not an area. isArea = false; } if (isArea) { // area tags leads to simple polygon LineairRing lineairRing = new LineairRing((osmObject as CompleteWay).GetCoordinates().ToArray<GeoCoordinate>()); lineairRing.Attributes = new SimpleGeometryAttributeCollection(tags); collection.Add(lineairRing); } else { // no area tag leads to just a line. LineString lineString = new LineString((osmObject as CompleteWay).GetCoordinates().ToArray<GeoCoordinate>()); lineString.Attributes = new SimpleGeometryAttributeCollection(tags); collection.Add(lineString); } break; case CompleteOsmType.Relation: CompleteRelation relation = (osmObject as CompleteRelation); tags = relation.Tags; string typeValue; if (tags.TryGetValue("type", out typeValue)) { // there is a type in this relation. if (typeValue == "multipolygon") { // this relation is a multipolygon. Geometry geometry = this.InterpretMultipolygonRelation(relation); if (geometry != null) { // add the geometry. collection.Add(geometry); } } else if (typeValue == "boundary") { // this relation is a boundary. } } break; } } return collection; }
// Token: 0x060077BC RID: 30652 RVA: 0x00222C78 File Offset: 0x00220E78 private void DrawBackgound(DrawingContext drawingContext) { PathGeometry pathGeometry = null; int count = this._elementsBounds.Count; Geometry geometry; if (count != 0) { for (int i = 0; i < count; i++) { Rect rect = this._elementsBounds[i]; if (!rect.IsEmpty) { rect.Inflate(3.0, 3.0); if (pathGeometry == null) { PathFigure pathFigure = new PathFigure(); pathFigure.StartPoint = new Point(rect.Left, rect.Top); PathSegmentCollection pathSegmentCollection = new PathSegmentCollection(); PathSegment pathSegment = new LineSegment(new Point(rect.Right, rect.Top), true); pathSegment.Freeze(); pathSegmentCollection.Add(pathSegment); pathSegment = new LineSegment(new Point(rect.Right, rect.Bottom), true); pathSegment.Freeze(); pathSegmentCollection.Add(pathSegment); pathSegment = new LineSegment(new Point(rect.Left, rect.Bottom), true); pathSegment.Freeze(); pathSegmentCollection.Add(pathSegment); pathSegment = new LineSegment(new Point(rect.Left, rect.Top), true); pathSegment.Freeze(); pathSegmentCollection.Add(pathSegment); pathSegmentCollection.Freeze(); pathFigure.Segments = pathSegmentCollection; pathFigure.IsClosed = true; pathFigure.Freeze(); pathGeometry = new PathGeometry(); pathGeometry.Figures.Add(pathFigure); } else { geometry = new RectangleGeometry(rect); geometry.Freeze(); pathGeometry = Geometry.Combine(pathGeometry, geometry, GeometryCombineMode.Union, null); } } } } GeometryGroup geometryGroup = new GeometryGroup(); GeometryCollection geometryCollection = new GeometryCollection(); geometry = new RectangleGeometry(new Rect(0.0, 0.0, base.RenderSize.Width, base.RenderSize.Height)); geometry.Freeze(); geometryCollection.Add(geometry); Geometry geometry2 = null; if (pathGeometry != null) { pathGeometry.Freeze(); geometry2 = pathGeometry.GetOutlinedPathGeometry(); geometry2.Freeze(); if (count == 1 && ((InkCanvasInnerCanvas)base.AdornedElement).InkCanvas.GetSelectedStrokes().Count == 0) { geometryCollection.Add(geometry2); } } geometryCollection.Freeze(); geometryGroup.Children = geometryCollection; geometryGroup.Freeze(); drawingContext.DrawGeometry(Brushes.Transparent, null, geometryGroup); if (geometry2 != null) { drawingContext.DrawGeometry(null, this._hatchPen, geometry2); } }
private void AggregateChildren(SvgAElement aElement, WpfDrawingContext context, float opacity) { _isAggregated = false; if (aElement == null || aElement.ChildNodes == null) { return; } string aggregatedFill = aElement.GetAttribute("fill"); bool isFillFound = !String.IsNullOrEmpty(aggregatedFill); SvgStyleableElement paintElement = null; if (isFillFound) { paintElement = aElement; } XmlNode targetNode = aElement; // Check if the children of the link are wrapped in a Group Element... if (aElement.ChildNodes.Count == 1) { SvgGElement groupElement = aElement.ChildNodes[0] as SvgGElement; if (groupElement != null) { targetNode = groupElement; } } WpfDrawingSettings settings = context.Settings; GeometryCollection geomColl = new GeometryCollection(); foreach (XmlNode node in targetNode.ChildNodes) { if (node.NodeType != XmlNodeType.Element) { continue; } // Handle a case where the clip element has "use" element as a child... if (String.Equals(node.LocalName, "use")) { SvgUseElement useElement = (SvgUseElement)node; XmlElement refEl = useElement.ReferencedElement; if (refEl != null) { XmlElement refElParent = (XmlElement)refEl.ParentNode; useElement.OwnerDocument.Static = true; useElement.CopyToReferencedElement(refEl); refElParent.RemoveChild(refEl); useElement.AppendChild(refEl); foreach (XmlNode useChild in useElement.ChildNodes) { if (useChild.NodeType != XmlNodeType.Element) { continue; } SvgStyleableElement element = useChild as SvgStyleableElement; if (element != null && element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = WpfRendering.CreateGeometry(element, settings.OptimizePath); if (childPath != null) { if (isFillFound) { string elementFill = element.GetAttribute("fill"); if (!String.IsNullOrEmpty(elementFill) && !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase)) { return; } } else { aggregatedFill = element.GetAttribute("fill"); isFillFound = !String.IsNullOrEmpty(aggregatedFill); if (isFillFound) { paintElement = element; } } geomColl.Add(childPath); } } } useElement.RemoveChild(refEl); useElement.RestoreReferencedElement(refEl); refElParent.AppendChild(refEl); useElement.OwnerDocument.Static = false; } } //else if (String.Equals(node.LocalName, "g")) //{ //} else { SvgStyleableElement element = node as SvgStyleableElement; if (element != null && element.RenderingHint == SvgRenderingHint.Shape) { Geometry childPath = WpfRendering.CreateGeometry(element, settings.OptimizePath); if (childPath != null) { if (isFillFound) { string elementFill = element.GetAttribute("fill"); if (!String.IsNullOrEmpty(elementFill) && !String.Equals(elementFill, aggregatedFill, StringComparison.OrdinalIgnoreCase)) { return; } } else { aggregatedFill = element.GetAttribute("fill"); isFillFound = !String.IsNullOrEmpty(aggregatedFill); if (isFillFound) { paintElement = element; } } geomColl.Add(childPath); } } } } if (geomColl.Count == 0 || paintElement == null) { return; } _aggregatedFill = paintElement; _aggregatedGeom = geomColl; _isAggregated = true; }
/// <summary> /// Применяет последовательность преобразований к коллекции линейных объектов. /// </summary> /// <param name="sourceGeometries">Коллекция линейных объектов</param> /// <returns>Коллекция преобразованных объектов</returns> public GeometryCollection GetLines(GeometryCollection sourceGeometries) { GeometryCollection tempSource = new GeometryCollection(); foreach (IGeometry g in sourceGeometries) tempSource.Add(g); GeometryCollection result = new GeometryCollection(); foreach (ILineTransformer transformer in _transformers) { result.Clear(); foreach (IGeometry g in tempSource) { if (g.CoordinateCount < 2) continue; GeometryCollection gc = null; if (g is LinePath) { gc = transformer.GetLines((LinePath)g); } else if (g is Contour) { gc = transformer.GetLines((Contour)g); } else throw new ArgumentException("Source collection should contain only contours and linepaths.", "sourceGeometries"); foreach(IGeometry g1 in gc) { if(!(g1 is LinePath || g1 is Contour)) throw new InvalidOperationException("LineTransformation \"" + transformer.GetType().FullName + "\" has wrong output."); result.Add(g1); } } tempSource.Clear(); foreach (IGeometry g in result) tempSource.Add(g); } return result; }
/// <summary> /// Преобразует ломаную линию в коллекцию линейных объектов. /// </summary> /// <param name="path">Ломаная линия</param> /// <returns>Коллекция линейных объектов (LinePath и Contour)</returns> public GeometryCollection GetLines(LinePath path) { GeometryCollection result = new GeometryCollection(); double length = path.Length(); double strokePatternLength = 0; foreach (double d in _strokes) strokePatternLength += d; double offset = _offset % strokePatternLength; double currentLength = offset; double traversedLength = 0; int segmentIndex = 0; int strokeIndex = 0; while (currentLength < length) { double strokeLength = _strokes[strokeIndex]; List<ICoordinate> strokePoints = getStrokePoints(path.Vertices, currentLength, strokeLength, ref segmentIndex, ref traversedLength); if (strokePoints.Count > 0) { LinePath lp = new LinePath(); foreach (ICoordinate p in strokePoints) lp.Vertices.Add(p); result.Add(lp); } currentLength += strokeLength; strokeIndex++; currentLength += _strokes[strokeIndex]; if (strokeIndex == _strokes.Length - 1) strokeIndex = 0; else strokeIndex++; } currentLength = offset; bool isSpace = true; for (int i = _strokes.Length - 1; i >= 0; i--) { double strokeLength = _strokes[i]; if (strokeLength > currentLength) strokeLength = currentLength; currentLength -= strokeLength; traversedLength = 0; segmentIndex = 0; if (!isSpace) { List<ICoordinate> strokePoints = getStrokePoints(path.Vertices, currentLength, strokeLength, ref segmentIndex, ref traversedLength); if (strokePoints.Count > 0) { LinePath lp = new LinePath(); foreach (ICoordinate p in strokePoints) lp.Vertices.Add(p); result.Add(lp); } } if (currentLength == 0) break; isSpace = !isSpace; } return result; }
private static GeoPolygon getPolylineBuffer(GeoPolyline geoPolyline, double angleDistance, int pointsPerCircle, bool allowParallels) { geoPolyline = (GeoPolyline)geoPolyline.Clone(); double minAngle = Math.Sin(Math.Abs(angleDistance)) * Math.Sin(Math.PI / pointsPerCircle); geoPolyline.ReduceSegments(minAngle); geoPolyline.Densify(minAngle); GnomonicProjection projection; IGeometry geometry; projectGeography(geoPolyline, out projection, out geometry); Polyline planePolyline = (Polyline)geometry; GeographyCollection geographyCollection = new GeographyCollection(); Polygon temp = new Polygon(); List<Polygon> partialBuffers = new List<Polygon>(); ICollection<IGeometry> unionResult = null; int c = 0; foreach (GeoPath path in geoPolyline.Paths) { for (int i = 0; i < path.Vertices.Count - 1; i++) { GeoPoint p = path.Vertices[i]; GeoPolygon tempPolygon = getPointBuffer(p, angleDistance, pointsPerCircle); geographyCollection.Clear(); geographyCollection.Add(tempPolygon); GeometryCollection gc = GeometrySpreader.GetGeometries(geographyCollection, projection); if (gc[0] is Polygon) unionResult = temp.Union((Polygon)gc[0]); if (unionResult.Count > 0) temp = (Polygon)((GeometryCollection)unionResult)[0]; c++; if (c == 3) { partialBuffers.Add(temp); temp = new Polygon(); c = 0; } } } if (temp.CoordinateCount > 0) partialBuffers.Add(temp); Polygon planeBuffer = mergePartialBuffers(partialBuffers, allowParallels); GeometryCollection geometryCollection = new GeometryCollection(); geometryCollection.Add(planeBuffer); geographyCollection = GeometrySpreader.GetGeographies(geometryCollection, projection); foreach (IGeography g in geographyCollection) if (g is GeoPolygon) return (GeoPolygon)g; return new GeoPolygon(); }