// 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); }
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(); }