/** * Returns true if this extent intersects the minimum bounding rectangle * that encompasses a set of points. * @param input * Points to test against extent. */ public bool intersectsExtent(GeoPointList input) { GeoExtent input_extent = new GeoExtent(); input_extent.expandToInclude(input); return(intersects(input_extent)); }
/** * Modifies this extent to include a set of points. * @param points * Points to include. */ public void expandToInclude(GeoPointList input) { foreach (GeoPoint i in input) { expandToInclude(i); } }
/** * Adds a new part to the shape, preallocating space for the points, * and returns a reference to it. * @param num_points * The number of points to preallocate in the part. */ public GeoPointList addPart(int num_points) { extent_cache = GeoExtent.invalid(); GeoPointList list = new GeoPointList(num_points); parts.Add(list); return(list); }
/** * Returns if an entire set of points falls within this extent. * @param input * Set of points to test. */ public bool contains(GeoPointList input) { for (int i = 0; i < input.Count; i++) { if (!contains(input[i])) { return(false); } } return(true); }
static void bufferPolygons(GeoShape shape, double b, out GeoPartList output) { foreach (GeoPointList i in shape.getParts()) { GeoPointList part = i; if (part.Count < 3) { continue; } GeoPointList new_part; // first build the buffered line segments: SegmentList segments; foreach (GeoPoint j in part) { Vector3D p0 = j; Vector3D p1 = (j + 1) != part.end() ? *(j + 1) : *part.begin(); Vector3D d = p1 - p0; d.Normalize(); Vector3D b0 = new Vector3D(p0.X + b * d.Y, p0.Y - b * d.X, p1.z()); Vector3D b1 = new Vector3D(p1.X + b * d.Y, p1.Y - b * d.X, p1.z()); segments.Add(new Segment(b0, b1)); } // then intersect each pair of segments to find the new verts: foreach (Segment k in segments) { Segment s0 = k; Segment s1 = (k + 1) != segments.end() ? *(k + 1) : *segments.begin(); Vector3D isect; if (getLineIntersection(s0, s1, isect)) { GeoPoint r = new GeoPoint(isect, part[0].getSRS()); r.setDim(part[0].getDim()); new_part.Add(r); } } if (new_part.Count > 2) { output.Add(new_part); } } }
/** * Visits each point in the shape with a user-provided visitor. */ public bool accept(GeoPointVisitor visitor) { extent_cache = GeoExtent.invalid(); for (int pi = 0; pi < getPartCount(); pi++) { GeoPointList part = getPart(pi); for (int vi = 0; vi < part.Count; vi++) { if (!visitor.visitPoint(part[vi])) { return(false); } } } return(true); }
public bool intersects(GeoExtent ex) { if (ex.isInfinite()) { return(true); } if (ex.isPoint()) { GeoPoint point = ex.sw; bool result = false; GeoPointList polygon = this; for (int i = 0, j = polygon.Count - 1; i < polygon.Count; j = i++) { if ((((polygon[i].Y <= point.Y) && (point.Y < polygon[j].Y)) || ((polygon[j].Y <= point.Y) && (point.Y < polygon[i].Y))) && (point.X < (polygon[j].X - polygon[i].X) * (point.Y - polygon[i].Y) / (polygon[j].Y - polygon[i].Y) + polygon[i].X)) { result = !result; } } return(result); } else //check for all points within extent -- not actually correct //TODO { GeoExtent e; e = new GeoExtent(this[0], this[0]); foreach (GeoPoint geoPoint in this) { if (geoPoint == this[0]) { //NOP } else { e.expandToInclude(geoPoint); } } return(e.intersects(ex)); } }
public override int getShapeDim() { throw new NotImplementedException(); int dim = 2; if (getShapes().Count > 0) { GeoShape shape0 = getShapes()[0]; if (shape0.getPartCount() > 0) { GeoPointList part0 = shape0.getPart(0); if (part0.Count > 0) { GeoPoint p0 = part0[0]; dim = (int)p0.getDim(); } } } return(dim); }
// ensures that all single-part shapes have their verts wound CCW. static Feature wind(Feature input) { #if TODO if (input.getShapeType() == GeoShape.ShapeType.TYPE_POLYGON) { foreach (GeoShape i in input.getShapes()) { GeoShape shape = i; if (shape.getPartCount() == 1) { GeoPointList part = shape.getPart(0); GeomUtils.openPolygon(part); if (!GeomUtils.isPolygonCCW(part)) { std.reverse(part.begin(), part.end()); } } } } return(input); #endif throw new NotImplementedException(); }
public bool visitPart(GeoPointList part) { return(true); }
public override FragmentList process(Feature input, FilterEnv env) { FragmentList output; // LIMITATION: this filter assumes all feature's shapes are the same // shape type! TODO: sort into bins of shape type and create a separate // geometry for each. Then merge the geometries. bool needs_tessellation = false; Fragment frag = new Fragment(); GeoShapeList shapes = input.getShapes(); #if TODO // if we're in batch mode, the color was resolved in the other process() function. // otherwise we still need to resolve it. Vector4D color = getColorForFeature(input, env); #endif #if TODO foreach (GeoShape s in shapes) { GeoShape shape = s; if (shape.getShapeType() == GeoShape.ShapeType.TYPE_POLYGON) { needs_tessellation = true; } osg.Geometry geom = new osg.Geometry(); // TODO: pre-total points and pre-allocate these arrays: osg.Vec3Array verts = new osg.Vec3Array(); geom.setVertexArray(verts); uint vert_ptr = 0; // per-vertex coloring takes more memory than per-primitive-set coloring, // but it renders faster. osg.Vec4Array colors = new osg.Vec4Array(); geom.setColorArray(colors); geom.setColorBinding(osg.Geometry.BIND_PER_VERTEX); //osg.Vec3Array* normals = new osg.Vec3Array(); //geom.setNormalArray( normals ); //geom.setNormalBinding( osg.Geometry.BIND_OVERALL ); //normals.push_back( osg.Vec3( 0, 0, 1 ) ); Mogre.PixelFormat prim_type = shape.getShapeType() == GeoShape.ShapeType.TYPE_POINT ? osg.PrimitiveSet.POINTS : shape.getShapeType() == GeoShape.ShapeType.TYPE_LINE ? osg.PrimitiveSet.LINE_STRIP : osg.PrimitiveSet.LINE_LOOP; #endif #if TODO for (int pi = 0; pi < shape.getPartCount(); pi++) { int part_ptr = vert_ptr; GeoPointList points = shape.getPart(pi); for (int vi = 0; vi < points.Count; vi++) { verts.Add(points[vi]); vert_ptr++; colors.Add(color); } geom.addPrimitiveSet(new osg.DrawArrays(prim_type, part_ptr, vert_ptr - part_ptr)); } // tessellate all polygon geometries. Tessellating each geometry separately // with TESS_TYPE_GEOMETRY is much faster than doing the whole bunch together // using TESS_TYPE_DRAWABLE. if (needs_tessellation) { osgUtil.Tessellator tess; tess.setTessellationType(osgUtil.Tessellator.TESS_TYPE_GEOMETRY); tess.setWindingType(osgUtil.Tessellator.TESS_WINDING_POSITIVE); tess.retessellatePolygons(*geom); applyOverlayTexturing(geom, input, env); } generateNormals(geom); frag.addDrawable(geom); } frag.addAttributes(input.getAttributes()); applyFragmentName(frag, input, env); output.Add(frag); return(output); #endif throw new NotImplementedException(); }
/** * Adds a part to the shape and returns a reference to it. */ public GeoPointList addPart(GeoPointList part) { extent_cache = GeoExtent.invalid(); parts.Add(part); return(part); }
static void bufferLinesToLines(GeoShape input, double b, GeoShape output) { // buffering lines turns them into polygons foreach (GeoPointList i in input.getParts()) { GeoPointList part = i; if (part.Count < 2) { continue; } GeoPointList new_part; // collect all the shifted segments: SegmentList segments; foreach (GeoPoint j in part) { Vector3D p0 = j; Vector3D p1 = *(j + 1); Vector3D d = p1 - p0; d.Normalize(); Vector3D b0 = new Vector3D(p0.X + b * d.Y, p0.Y - b * d.X, p1.Z); Vector3D b1 = new Vector3D(p1.X + b * d.Y, p1.Y - b * d.X, p1.Z); segments.Add(new Segment(b0, b1)); } // then intersect each pair of shifted segments to find the new verts: foreach (Segment k in segments) { Segment s0 = k; Segment s1 = *(k + 1); //(k+1) != segments.end()? *(k+1) : *segments.begin(); if (k == segments.begin()) { GeoPoint first = new GeoPoint(s0.p0, part[0].getSRS()); first.setDim(part[0].getDim()); new_part.Add(first); } Vector3D isect; if (getLineIntersection(s0, s1, out isect)) { GeoPoint r = new GeoPoint(isect, part[0].getSRS()); r.setDim(part[0].getDim()); new_part.Add(r); } if (k == segments.end() - 2) { GeoPoint last = new GeoPoint(s1.p1, part[0].getSRS()); last.setDim(part[0].getDim()); new_part.Add(last); } } if (new_part.Count > 1) { output.getParts().Add(new_part); } } }
static void bufferLinesToPolygons(GeoShape input, double b, GeoShape output) { // buffering lines turns them into polygons foreach (GeoPointList i in input.getParts()) { GeoPointList part = i; if (part.Count < 2) { continue; } GeoPointList new_part; // collect segments in one direction and then the other. SegmentList segments; foreach (GeoPoint j in part) { Vector3D p0 = j; Vector3D p1 = *(j + 1); Vector3D d = p1 - p0; d.Normalize(); Vector3D b0 = new Vector3D(p0.X + b * d.Y, p0.Y - b * d.X, p1.Z); Vector3D b1 = new Vector3D(p1.X + b * d.Y, p1.Y - b * d.X, p1.Z); segments.Add(new Segment(b0, b1)); // after the last seg, add an end-cap: if (j == part.end() - 2) { Vector3D b2 = new Vector3D(p1.X - b * d.Y, p1.Y + b * d.X, p1.Z); segments.Add(new Segment(b1, b2)); } } // now back the other way: foreach (GeoPoint j in part) //TODO IS IN REVERSE !! { Vector3D p0 = j; Vector3D p1 = *(j + 1); Vector3D d = p1 - p0; d.Normalize(); Vector3D b0 = new Vector3D(p0.X + b * d.Y, p0.Y - b * d.X, p1.Z); Vector3D b1 = new Vector3D(p1.X + b * d.Y, p1.Y - b * d.X, p1.Z); segments.Add(new Segment(b0, b1)); // after the last seg, add an end-cap: if (j == part.rend() - 2) { Vector3D b2 = new Vector3D(p1.X - b * d.Y, p1.Y + b * d.X, p1.z()); segments.Add(new Segment(b1, b2)); } } // then intersect each pair of segments to find the new verts: foreach (Segment k in segments) { Segment s0 = k; Segment s1 = (k + 1) != segments.end() ? *(k + 1) : *segments.begin(); Vector3D isect; if (getLineIntersection(s0, s1, out isect)) { GeoPoint r = new GeoPoint(isect, part[0].getSRS()); r.setDim(part[0].getDim()); new_part.Add(r); } } if (new_part.Count > 2) { output.getParts().Add(new_part); } } }