// FeatureFilter overrides public FeatureList process(Feature input, FilterEnv env) { FeatureList output; GeoShapeList shapes = input.getShapes(); GeoShapeList new_shapes; double b = getDistance(); if (env.getInputSRS().isGeographic()) { // for geo, convert from meters to degrees //TODO: we SHOULD do this for each and every feature buffer segment, but // for how this is a shortcut approximation. double bc = b / 1.4142; Vector2D vec = new Vector2D(bc, bc); //vec.normalize(); GeoPoint c = input.getExtent().getCentroid(); Vector2D p0 = new Vector2D(c.X, c.Y); Vector2D p1; Units.convertLinearToAngularVector(vec, Units.METERS, Units.DEGREES, p0, p1); b = (p1 - p0).GetLength(); } foreach (GeoPointList i in shapes) { GeoPartList new_parts; GeoShape shape = i; if (shape.getShapeType() == GeoShape.ShapeType.TYPE_POLYGON) { GeoShape new_shape = new GeoShape(GeoShape.ShapeType.TYPE_POLYGON, shape.getSRS()); bufferPolygons(shape, b, out new_shape.getParts()); new_shapes.Add(new_shape); } else if (shape.getShapeType() == GeoShape.ShapeType.TYPE_LINE) { if (getConvertToPolygon()) { GeoShape new_shape = new GeoShape(GeoShape.ShapeType.TYPE_POLYGON, shape.getSRS()); bufferLinesToPolygons(shape, b, new_shape); new_shapes.Add(new_shape); } else { GeoShape new_shape = new GeoShape(GeoShape.ShapeType.TYPE_LINE, shape.getSRS()); bufferLinesToLines(shape, b, new_shape); new_shapes.Add(new_shape); } } } if (new_shapes.Count > 0) { input.getShapes().swap(new_shapes); } output.Add(input); return(output); }
/** * Copy constructor. */ public GeoShape(GeoShape rhs) { shape_type = rhs.shape_type; parts = rhs.parts; extent_cache = rhs.extent_cache; srs = rhs.srs; }
public override double getArea() { throw new NotImplementedException(); double area = 0.0; foreach (GeoShape i in getShapes()) { if (!i.getSRS().isProjected()) { GeoShape shape = Registry.SRSFactory().createCEA().transform(i); foreach (GeoPart j in shape.getParts()) { area += Math.Abs(GeomUtils.getPolygonArea2D(j)); } } else { foreach (GeoPart j in i.getParts()) { area += Math.Abs(GeomUtils.getPolygonArea2D(j)); } } } return(area); }
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); } } }
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 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(); }
protected void applyTo(GeoShape shape) { shape.setSpatialReference(this); }
/** * Transforms a shape into this SRS (modifying the input data). * * @param input * Shape to transform into this SRS * @return * True upon success, false upon failure. */ public abstract bool transformInPlace(GeoShape input);
/** * Returns a shape transformed into this SRS. * * @param input * Shape to transform into this SRS * @return * Transformed shape, or GeoShape::invalid() upon failure */ public abstract GeoShape transform(GeoShape input);
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); } } }
public override bool transformInPlace(GeoShape input) { throw new NotImplementedException(); }
public override GeoShape transform(GeoShape input) { throw new NotImplementedException(); }