Package org.locationtech.udig.style.advanced.utils

Source Code of org.locationtech.udig.style.advanced.utils.Drawing

/* uDig - User Friendly Desktop Internet GIS client
* http://udig.refractions.net
* (C) 2004-2012, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*/
package org.locationtech.udig.style.advanced.utils;

import static java.lang.Math.toRadians;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.locationtech.udig.ui.graphics.AWTGraphics;
import org.locationtech.udig.ui.graphics.NonAdvancedSWTGraphics;
import org.locationtech.udig.ui.graphics.SLDs;
import org.locationtech.udig.ui.graphics.SWTGraphics;
import org.locationtech.udig.ui.graphics.ViewportGraphics;

import org.eclipse.core.runtime.Platform;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.geotools.data.DataUtilities;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.LiteShape;
import org.geotools.renderer.style.GraphicStyle2D;
import org.geotools.renderer.style.MarkStyle2D;
import org.geotools.renderer.style.SLDStyleFactory;
import org.geotools.renderer.style.Style2D;
import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.Graphic;
import org.geotools.styling.LineSymbolizer;
import org.geotools.styling.Mark;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.PolygonSymbolizer;
import org.geotools.styling.RasterSymbolizer;
import org.geotools.styling.Rule;
import org.geotools.styling.Stroke;
import org.geotools.styling.Style;
import org.geotools.styling.StyleBuilder;
import org.geotools.styling.Symbolizer;
import org.geotools.styling.TextSymbolizer;
import org.geotools.util.NumberRange;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.expression.Expression;
import org.opengis.geometry.BoundingBox;
import org.opengis.referencing.operation.MathTransform;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;

import org.locationtech.udig.style.advanced.common.styleattributeclasses.PointSymbolizerWrapper;

/**
* Drawing utility package - make your own previews and glyphs!
*
* @author jones
* @since 0.6.0
*/
public final class Drawing {
    private GeometryFactory gf = new GeometryFactory();

    private Drawing() {
        // prevent subclassing
    }

    /**
     * Retrieve the default Drawing implementation.
     *
     * @return Drawing ready for use
     */
    public static Drawing create() {
        return new Drawing();
    }

    /**
     * Creates a ViewportGraphics object based backed by SWT.
     *
     * <p><b>REMEMBER to dispose of graphics.</b>
     *
     * @param gc A SWT GC object that the ViewportGraphics object will draw on.
     * @param display The display object that will be used to create new
     * @param displaySize
     * @return Wrapper around a normal SWT Image
     */
    public static ViewportGraphics createGraphics( GC gc, Display display, Dimension displaySize ) {
        if (Platform.getOS().equals(Platform.OS_LINUX))

            return new NonAdvancedSWTGraphics(gc, display, displaySize);

        return new SWTGraphics(gc, display);
    }
    /**
     * Creates a ViewportGraphics object based backed by SWT.
     *
     * @param graphics
     * @return Wrapper allowing system to draw onto j2d images
     */
    public static ViewportGraphics createGraphics( Graphics2D graphics ) {
        return new AWTGraphics(graphics);
    }

    /**
     * Used to draw a freature directly onto the provided image.
     * <p>
     * SimpleFeature coordintes are in the same coordinates as the image.
     * </p>
     * <p>
     * You may call this method multiple times to draw several features onto the same
     * Image (say for glyph creation).
     * </p>
    
     * @param image Image to render on to
     * @param display Needed to create Colors for image
     * @param feature SimpleFeature to be rendered
     * @param style Style to render feature with
     */
    public void drawDirect( Image image, Display display, SimpleFeature feature, Style style ) {

        ViewportGraphics graphics = createSWTGraphics(image, display);
        drawFeature(graphics, feature, style, new AffineTransform());
        graphics.dispose();
    }

    public void drawDirect( Image image, Display display, SimpleFeature feature, Rule rule ) {
        AffineTransform worldToScreenTransform = new AffineTransform();

        ViewportGraphics graphics = createSWTGraphics(image, display);
        drawFeature(graphics, feature, worldToScreenTransform, false, getSymbolizers(rule), null);
        graphics.dispose();
    }

    public void drawDirect( BufferedImage image, SimpleFeature feature, Rule rule ) {
        AffineTransform worldToScreenTransform = new AffineTransform();
        ViewportGraphics graphics = createGraphics(image.createGraphics());
        drawFeature(graphics, feature, worldToScreenTransform, false, getSymbolizers(rule), null);
        graphics.dispose();
    }

    /**
     *
     * @param image
     * @param display
     * @return
     */
    private ViewportGraphics createSWTGraphics( Image image, Display display ) {
        if (Platform.getOS().equals(Platform.OS_LINUX))
            return new NonAdvancedSWTGraphics(image, display);
        return new SWTGraphics(image, display);
    }

    public void drawFeature( ViewportGraphics graphics, SimpleFeature feature, AffineTransform worldToScreenTransform,
            boolean drawVertices, MathTransform mt ) {
        if (feature == null)
            return;
        drawFeature(graphics, feature, worldToScreenTransform, drawVertices, getSymbolizers(feature), mt);
    }

    public void drawFeature( ViewportGraphics graphics, SimpleFeature feature, AffineTransform worldToScreenTransform ) {
        if (feature == null)
            return;
        drawFeature(graphics, feature, worldToScreenTransform, false, getSymbolizers(feature), null);
    }

    public void drawFeature( ViewportGraphics graphics, SimpleFeature feature, AffineTransform worldToScreenTransform, Style style ) {
        if (feature == null)
            return;
        drawFeature(graphics, feature, worldToScreenTransform, false, getSymbolizers(style), null);
    }

    public void drawFeature( ViewportGraphics graphics, SimpleFeature feature, Style style, AffineTransform worldToScreenTransform ) {
        if (feature == null)
            return;

        drawFeature(graphics, feature, worldToScreenTransform, false, getSymbolizers(style), null);
    }

    Symbolizer[] getSymbolizers( Style style ) {
        List<Symbolizer> symbs = new ArrayList<Symbolizer>();
        FeatureTypeStyle[] styles = style.getFeatureTypeStyles();
        for( int i = 0; i < styles.length; i++ ) {
            FeatureTypeStyle fstyle = styles[i];
            Rule[] rules = fstyle.getRules();
            for( int j = 0; j < rules.length; j++ ) {
                Rule rule = rules[j];
                symbs.addAll(Arrays.asList(rule.getSymbolizers()));
            }
        }
        return symbs.toArray(new Symbolizer[symbs.size()]);
    }

    Symbolizer[] getSymbolizers( Rule rule ) {
        List<Symbolizer> symbs = new ArrayList<Symbolizer>();
        symbs.addAll(Arrays.asList(rule.getSymbolizers()));
        return symbs.toArray(new Symbolizer[symbs.size()]);
    }

    public void drawFeature( ViewportGraphics graphics, SimpleFeature feature, AffineTransform worldToScreenTransform,
            boolean drawVertices, Symbolizer[] symbs, MathTransform mt ) {

        LiteShape shape = new LiteShape(null, worldToScreenTransform, false);
        if (symbs == null)
            return;
        for( int m = 0; m < symbs.length; m++ ) {
            drawFeature(graphics, feature, worldToScreenTransform, drawVertices, symbs[m], mt, shape);
        }
    }

    public void drawFeature( ViewportGraphics graphics, SimpleFeature feature, AffineTransform worldToScreenTransform,
            boolean drawVertices, Symbolizer symbolizer, MathTransform mathTransform, LiteShape shape ) {
        if (symbolizer instanceof RasterSymbolizer) {
            // TODO
        } else {
            Geometry g = findGeometry(feature, symbolizer);
            if (g == null)
                return;
            if (mathTransform != null) {
                try {
                    g = JTS.transform(g, mathTransform);
                } catch (Exception e) {
                    // do nothing
                }
            }
            shape.setGeometry(g);

            paint(graphics, feature, shape, symbolizer);
            if (drawVertices) {
                double averageDistance = 0;
                Coordinate[] coords = g.getCoordinates();
                java.awt.Point oldP = worldToPixel(coords[0], worldToScreenTransform);
                for( int i = 1; i < coords.length; i++ ) {
                    Coordinate coord = coords[i];
                    java.awt.Point p = worldToPixel(coord, worldToScreenTransform);
                    averageDistance += p.distance(oldP) / i;
                    oldP = p;
                }
                int pixels = 1;
                if (averageDistance > 20)
                    pixels = 3;
                if (averageDistance > 60)
                    pixels = 5;
                if (pixels > 1) {
                    graphics.setColor(Color.RED);
                    for( int i = 0; i < coords.length; i++ ) {
                        Coordinate coord = coords[i];
                        java.awt.Point p = worldToPixel(coord, worldToScreenTransform);
                        graphics.fillRect(p.x - (pixels - 1) / 2, p.y - (pixels - 1) / 2, pixels, pixels);
                    }
                }
            }
        }
    }

    public java.awt.Point worldToPixel( Coordinate coord, AffineTransform worldToScreenTransform ) {
        Point2D w = new Point2D.Double(coord.x, coord.y);
        AffineTransform at = worldToScreenTransform;
        Point2D p = at.transform(w, new Point2D.Double());
        return new java.awt.Point((int) p.getX(), (int) p.getY());
    }

    /** Unsure if this is the paint for the border, or the fill? */
    private void paint( ViewportGraphics g, SimpleFeature feature, LiteShape shape, Symbolizer symb ) {
        if (symb instanceof PolygonSymbolizer) {
            PolygonSymbolizer polySymb = (PolygonSymbolizer) symb;
            double opacity = SLDs.polyFillOpacity(polySymb);
            Color fillColor = SLDs.polyFill(polySymb);
            Stroke stroke = SLDs.stroke(polySymb);
            Color strokeColor = SLDs.polyColor(polySymb);

            int width = SLDs.width(stroke);
            if (width == SLDs.NOTFOUND)
                width = 1;

            if (Double.isNaN(opacity))
                opacity = 1.0;
            if (fillColor != null) {
                fillColor = new Color(fillColor.getRed(), fillColor.getGreen(), fillColor.getBlue(), (int) (255 * opacity));
                g.setColor(fillColor);
                g.fill(shape);
            }
            if (stroke != null && strokeColor != null) {
                Graphics2D g2d = g.getGraphics(Graphics2D.class);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(strokeColor);

                float[] dashArray = stroke.getDashArray();
                Float dashOffset = stroke.getDashOffset().evaluate(null, Float.class);
                if (dashOffset == null) {
                    dashOffset = 0f;
                }
                String cap = stroke.getLineCap().evaluate(null, String.class);
                int capInt = Utilities.sld2awtCap(cap);
                String join = stroke.getLineJoin().evaluate(null, String.class);
                int joinInt = Utilities.sld2awtJoin(join);
                BasicStroke bStroke = new BasicStroke(width, capInt, joinInt, 1f, dashArray, dashOffset);
                g2d.setStroke(bStroke);
                g2d.draw(shape);
            }
        }
        if (symb instanceof LineSymbolizer) {
            LineSymbolizer lineSymbolizer = (LineSymbolizer) symb;
            Color c = SLDs.color(lineSymbolizer);
            int w = SLDs.width(lineSymbolizer);
            Stroke stroke = SLDs.stroke(lineSymbolizer);
            if (c != null && w > 0) {
                Graphics2D g2d = g.getGraphics(Graphics2D.class);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.setColor(c);

                float[] dashArray = stroke.getDashArray();
                Float dashOffset = stroke.getDashOffset().evaluate(null, Float.class);
                if (dashOffset == null) {
                    dashOffset = 0f;
                }
                String cap = stroke.getLineCap().evaluate(null, String.class);
                int capInt = Utilities.sld2awtCap(cap);
                String join = stroke.getLineJoin().evaluate(null, String.class);
                int joinInt = Utilities.sld2awtJoin(join);
                BasicStroke bStroke = new BasicStroke(w, capInt, joinInt, 1f, dashArray, dashOffset);
                g2d.setStroke(bStroke);
                g2d.draw(shape);
            }
        }
        if (symb instanceof PointSymbolizer) {
            PointSymbolizer pointSymbolizer = (PointSymbolizer) symb;

            AffineTransform transform = g.getTransform();

            // offset
            Point2D offset = Utilities.getOffset(pointSymbolizer);
            if (offset != null) {
                java.awt.Point off = new java.awt.Point((int) offset.getX(), -1 * (int) offset.getY());
                g.translate(off);
            }

            // rotation
            Graphic graphic = SLDs.graphic(pointSymbolizer);
            Double rotation = graphic.getRotation().evaluate(null, Double.class);
            Double gSize = graphic.getSize().evaluate(null, Double.class);
            if (gSize != null && rotation != null) {
                g.setTransform(AffineTransform.getRotateInstance(toRadians(rotation), gSize / 2, gSize / 2));
            }

            Color c = SLDs.pointStrokeColorWithAlpha(pointSymbolizer);
            Color fill = SLDs.pointFillWithAlpha(pointSymbolizer);
            int width = SLDs.width(SLDs.stroke(pointSymbolizer));
            if (width < 0) {
                width = 0;
            }
            float[] point = new float[6];
            PathIterator pathIterator = shape.getPathIterator(null);
            pathIterator.currentSegment(point);

            SLDStyleFactory styleFactory = new SLDStyleFactory();
            Style2D tmp = null;
            try {
                tmp = styleFactory.createStyle(feature, pointSymbolizer, new NumberRange(Double.class, Double.NEGATIVE_INFINITY,
                        Double.POSITIVE_INFINITY));
            } catch (Exception e) {
                PointSymbolizerWrapper tmpPs = new PointSymbolizerWrapper(pointSymbolizer, null);
                tmp = styleFactory.createStyle(feature, pointSymbolizer, new NumberRange(Double.class, Double.NEGATIVE_INFINITY,
                        Double.POSITIVE_INFINITY));
            }
            if (tmp instanceof MarkStyle2D) {
                MarkStyle2D style = (MarkStyle2D) tmp;
                Shape shape2 = style.getTransformedShape(point[0], point[1]);

                if (c == null && fill == null) {
                    // g.setColor(Color.GRAY);
                    // g.fill(shape2);
                }

                if (fill != null) {
                    g.setColor(fill);
                    g.fill(shape2);
                }
                // else {
                // g.setColor(Color.GRAY);
                // g.fill(shape2);
                // }
                if (c != null) {
                    g.setStroke(ViewportGraphics.LINE_SOLID, width);
                    g.setColor(c);
                    g.draw(shape2);
                }
                // else {
                // g.setStroke(ViewportGraphics.LINE_SOLID, width);
                // g.setColor(Color.DARK_GRAY);
                // g.draw(shape2);
                // }
            } else if (tmp instanceof GraphicStyle2D) {
                GraphicStyle2D style = (GraphicStyle2D) tmp;

                RenderedImage image = (RenderedImage) style.getImage();
                g.drawImage(image, (int) (point[0] - ((double) image.getWidth()) / (double) 2),
                        (int) (point[1] - ((double) image.getHeight()) / (double) 2));
            }
        }
    }
    public static Symbolizer[] getSymbolizers( SimpleFeature feature ) {
        return getSymbolizers((Class< ? extends Geometry>) feature.getDefaultGeometry().getClass(), Color.RED);
    }

    public static Symbolizer[] getSymbolizers( Class< ? extends Geometry> type, Color baseColor ) {
        return getSymbolizers(type, baseColor, true);
    }
    public static Symbolizer[] getSymbolizers( Class< ? extends Geometry> type, Color baseColor, boolean useTransparency ) {

        StyleBuilder builder = new StyleBuilder();
        Symbolizer[] syms = new Symbolizer[1];
        if (LineString.class.isAssignableFrom(type) || MultiLineString.class.isAssignableFrom(type))
            syms[0] = builder.createLineSymbolizer(baseColor, 2);
        if (Point.class.isAssignableFrom(type) || MultiPoint.class.isAssignableFrom(type)) {
            PointSymbolizer point = builder.createPointSymbolizer(builder.createGraphic());
            FilterFactory ff = builder.getFilterFactory();
            // point.getGraphic().getMarks()[0].setSize((Expression) ff.literal(10));
            point.getGraphic().setSize(ff.literal(10));
            Mark mark = (Mark) point.getGraphic().graphicalSymbols().get(0);
            mark.setFill(builder.createFill(baseColor));
            syms[0] = point;
        }
        if (Polygon.class.isAssignableFrom(type) || MultiPolygon.class.isAssignableFrom(type)) {
            syms[0] = builder.createPolygonSymbolizer(builder.createStroke(baseColor, 2),
                    builder.createFill(baseColor, useTransparency ? .6 : 1.0));
        }
        return syms;
    }

    /**
     * Finds the geometric attribute requested by the symbolizer.
     *
     * @param feature The victim
     * @param symbolizer The symbolizer
     * @param style the resolved style for the specified victim
     * @return The geometry requested in the symbolizer, or the default geometry if none is
     *         specified
     */
    private com.vividsolutions.jts.geom.Geometry findGeometry( SimpleFeature feature, Symbolizer symbolizer ) {
        String geomName = getGeometryPropertyName(symbolizer);
        // get the geometry
        com.vividsolutions.jts.geom.Geometry geometry;
        if (geomName == null || feature.getType().getDescriptor(geomName) == null) {
            geometry = (Geometry) feature.getDefaultGeometry();
        } else {
            geometry = (com.vividsolutions.jts.geom.Geometry) feature.getAttribute(geomName);
        }
        if (geometry == null) {
            return null; // nothing to see here
        }
        // if the symbolizer is a point or text symbolizer generate a suitable
        // location to place the
        // point in order to avoid recomputing that location at each rendering
        // step

        if ((symbolizer instanceof PointSymbolizer || symbolizer instanceof TextSymbolizer) && !(geometry instanceof Point)) {
            if (geometry instanceof LineString && !(geometry instanceof LinearRing)) {
                // use the mid point to represent the point/text symbolizer
                // anchor
                Coordinate[] coordinates = geometry.getCoordinates();
                Coordinate start = coordinates[0];
                Coordinate end = coordinates[1];
                Coordinate mid = new Coordinate((start.x + end.x) / 2, (start.y + end.y) / 2);
                geometry = geometry.getFactory().createPoint(mid);
            } else {
                // otherwise use the centroid of the polygon
                geometry = geometry.getCentroid();
            }
        }
        return geometry;
    }
    private String getGeometryPropertyName( Symbolizer s ) {
        String geomName = null;
        // TODO: fix the styles, the getGeometryPropertyName should probably be
        // moved into an interface...
        if (s instanceof PolygonSymbolizer) {
            geomName = ((PolygonSymbolizer) s).getGeometryPropertyName();
        } else if (s instanceof PointSymbolizer) {
            geomName = ((PointSymbolizer) s).getGeometryPropertyName();
        } else if (s instanceof LineSymbolizer) {
            geomName = ((LineSymbolizer) s).getGeometryPropertyName();
        } else if (s instanceof TextSymbolizer) {
            geomName = ((TextSymbolizer) s).getGeometryPropertyName();
        }
        return geomName;
    }
    /**
     * TODO summary sentence for worldToScreenTransform ...
     *
     * @param bounds
     * @param rectangle
     * @return
     */
    public static AffineTransform worldToScreenTransform( BoundingBox mapExtent, Rectangle screenSize ) {
        double scaleX = screenSize.getWidth() / mapExtent.getWidth();
        double scaleY = screenSize.getHeight() / mapExtent.getHeight();

        double tx = -mapExtent.getMinX() * scaleX;
        double ty = (mapExtent.getMinY() * scaleY) + screenSize.getHeight();

        AffineTransform at = new AffineTransform(scaleX, 0.0d, 0.0d, -scaleY, tx, ty);

        return at;
    }
    /**
     * Create a SimpleFeatureType schema using a type short hand.
     * <p>
     * Code Example:<pre><code>
     * new Drawing().schema("namespace.typename", "id:0,*geom:LineString,name:String,*centroid:Point");
     * </code></pre>
     * <ul>
     * <li>SimpleFeatureType with identifier "namespace.typename"
     * <li>Default Geometry "geom" of type LineStirng indicated with a "*"
     * <li>Three attributes: id of type Integer, name of type String and centroid of type Point
     * </ul>
     * </p>
     * @param name namespace.name
     * @param spec
     * @return Generated SimpleFeatureType
     */
    public SimpleFeatureType schema( String name, String spec ) {
        try {
            return DataUtilities.createType(name, spec);
        } catch (SchemaException e) {
            throw new IllegalArgumentException(e);
        }
    }

    static SimpleFeatureType pointSchema;
    static SimpleFeatureType lineSchema;
    static SimpleFeatureType polygonSchema;
    static SimpleFeatureType multipointSchema;
    static SimpleFeatureType multilineSchema;
    static SimpleFeatureType multipolygonSchema;
    static {
        try {
            pointSchema = DataUtilities.createType("generated:point", "*point:Point"); //$NON-NLS-1$ //$NON-NLS-2$
            lineSchema = DataUtilities.createType("generated:linestring", "*linestring:LineString"); //$NON-NLS-1$ //$NON-NLS-2$
            polygonSchema = DataUtilities.createType("generated:polygon", "*polygon:Polygon"); //$NON-NLS-1$ //$NON-NLS-2$
            multipointSchema = DataUtilities.createType("generated:multipoint", "*multipoint:MultiPoint"); //$NON-NLS-1$ //$NON-NLS-2$
            multilineSchema = DataUtilities.createType("generated:multilinestring", "*multilinestring:MultiLineString"); //$NON-NLS-1$ //$NON-NLS-2$
            multipolygonSchema = DataUtilities.createType("generated:multipolygon", "*multipolygon:MultiPolygon"); //$NON-NLS-1$ //$NON-NLS-2$
        } catch (SchemaException unExpected) {
            System.err.println(unExpected);
        }
    }

    /**
     * Just a convinient method to create feature from geometry.
     *
     * @param geom the geometry to create feature from
     * @return feature instance
     */
    public SimpleFeature feature( Geometry geom ) {
        if (geom instanceof Polygon) {
            return feature((Polygon) geom);
        } else if (geom instanceof MultiPolygon) {
            return feature((MultiPolygon) geom);
        } else if (geom instanceof Point) {
            return feature((Point) geom);
        } else if (geom instanceof LineString) {
            return feature((LineString) geom);
        } else if (geom instanceof MultiPoint) {
            return feature((MultiPoint) geom);
        } else if (geom instanceof MultiLineString) {
            return feature((MultiLineString) geom);
        } else {
            throw new IllegalArgumentException("Geometry is not supported to create feature"); //$NON-NLS-1$
        }
    }

    /**
     * Simple feature with one attribute called "point".
     * @param point
     * @return SimpleFeature with a default geometry and no attribtues
     */
    public SimpleFeature feature( Point point ) {
        if (point == null)
            throw new NullPointerException("Point required"); //$NON-NLS-1$
        try {
            return SimpleFeatureBuilder.build(pointSchema, new Object[]{point}, null);
        } catch (IllegalAttributeException e) {
            // this should not happen because we *know* the parameter matches schame
            throw new RuntimeException("Could not generate feature for point " + point); //$NON-NLS-1$
        }
    }
    /**
     * Simple SimpleFeature with a default geometry and no attribtues.
     * @param line
     * @return SimpleFeature with a default geometry and no attribtues
     */
    public SimpleFeature feature( LineString line ) {
        if (line == null)
            throw new NullPointerException("line required"); //$NON-NLS-1$
        try {
            return SimpleFeatureBuilder.build(lineSchema, new Object[]{line}, null);
        } catch (IllegalAttributeException e) {
            // this should not happen because we *know* the parameter matches schame
            throw new RuntimeException("Could not generate feature for point " + line); //$NON-NLS-1$
        }
    }

    /**
     * Simple SimpleFeature with a default geometry and no attribtues.
     * @param polygon
     * @return SimpleFeature with a default geometry and no attribtues
     */
    public SimpleFeature feature( Polygon polygon ) {
        if (polygon == null)
            throw new NullPointerException("polygon required"); //$NON-NLS-1$
        try {
            return SimpleFeatureBuilder.build(polygonSchema, new Object[]{polygon}, null);
        } catch (IllegalAttributeException e) {
            // this should not happen because we *know* the parameter matches schame
            throw new RuntimeException("Could not generate feature for point " + polygon); //$NON-NLS-1$
        }
    }

    /**
     * Simple SimpleFeature with a default geometry and no attribtues.
     * @param multipoint
     * @return SimpleFeature with a default geometry and no attribtues
     */
    public SimpleFeature feature( MultiPoint multipoint ) {
        if (multipoint == null)
            throw new NullPointerException("multipoint required"); //$NON-NLS-1$
        try {
            return SimpleFeatureBuilder.build(multipointSchema, new Object[]{multipoint}, null);
        } catch (IllegalAttributeException e) {
            // this should not happen because we *know* the parameter matches schame
            throw new RuntimeException("Could not generate feature for point " + multipoint); //$NON-NLS-1$
        }
    }
    /**
     * Simple SimpleFeature with a default geometry and no attribtues.
     * @param multilinestring
     * @return SimpleFeature with a default geometry and no attribtues
     */
    public SimpleFeature feature( MultiLineString multilinestring ) {
        if (multilinestring == null)
            throw new NullPointerException("multilinestring required"); //$NON-NLS-1$
        try {
            return SimpleFeatureBuilder.build(multilineSchema, new Object[]{multilinestring}, null);
        } catch (IllegalAttributeException e) {
            // this should not happen because we *know* the parameter matches schame
            throw new RuntimeException("Could not generate feature for point " + multilinestring); //$NON-NLS-1$
        }
    }
    /**
     * Simple SimpleFeature with a default geometry and no attribtues.
     * @param multipolygon
     * @return SimpleFeature with a default geometry and no attribtues
     */
    public SimpleFeature feature( MultiPolygon multipolygon ) {
        if (multipolygon == null)
            throw new NullPointerException("multipolygon required"); //$NON-NLS-1$
        try {
            return SimpleFeatureBuilder.build(multipolygonSchema, new Object[]{multipolygon}, null);
        } catch (IllegalAttributeException e) {
            // this should not happen because we *know* the parameter matches schame
            throw new RuntimeException("Could not generate feature for point " + multipolygon); //$NON-NLS-1$
        }
    }

    /**
     * Generate Point from two dimensional ordinates
     *
     * @param x
     * @param y
     * @return Point
     */
    public Point point( int x, int y ) {
        return gf.createPoint(new Coordinate(x, y));
    }
    /**
     * Generate LineStrings from two dimensional ordinates
     *
     * @param xy
     * @return LineStirng
     */
    public LineString line( int[] xy ) {
        Coordinate[] coords = new Coordinate[xy.length / 2];

        for( int i = 0; i < xy.length; i += 2 ) {
            coords[i / 2] = new Coordinate(xy[i], xy[i + 1]);
        }

        return gf.createLineString(coords);
    }

    /**
     * Generate a MultiLineString from two dimensional ordinates
     *
     * @param xy
     * @return MultiLineStirng
     */
    public MultiLineString lines( int[][] xy ) {
        LineString[] lines = new LineString[xy.length];

        for( int i = 0; i < xy.length; i++ ) {
            lines[i] = line(xy[i]);
        }

        return gf.createMultiLineString(lines);
    }
    /**
     * Convience constructor for GeometryFactory.createPolygon.
     * <p>
     * The provided xy ordinates are turned into a linear rings.
     * </p>
     * @param xy Two dimensional ordiantes.
     * @return Polygon
     */
    public Polygon polygon( int[] xy ) {
        LinearRing shell = ring(xy);
        return gf.createPolygon(shell, null);
    }

    /**
     * Convience constructor for GeometryFactory.createPolygon.
     * <p>
     * The provided xy and holes are turned into linear rings.
     * </p>
     * @param xy Two dimensional ordiantes.
     * @param holes Holes in polygon or null.
     *
     * @return Polygon
     */
    public Polygon polygon( int[] xy, int[] holes[] ) {
        if (holes == null || holes.length == 0) {
            return polygon(xy);
        }
        LinearRing shell = ring(xy);

        LinearRing[] rings = new LinearRing[holes.length];

        for( int i = 0; i < xy.length; i++ ) {
            rings[i] = ring(holes[i]);
        }
        return gf.createPolygon(shell, rings);
    }

    /**
     * Convience constructor for GeometryFactory.createLinearRing.
     *
     * @param xy Two dimensional ordiantes.
     * @return LinearRing for use with polygon
     */
    public LinearRing ring( int[] xy ) {
        int length = xy.length / 2;
        if (xy[0] != xy[xy.length - 2] || xy[1] != xy[xy.length - 1]) {
            length++;
        }
        Coordinate[] coords = new Coordinate[length];

        for( int i = 0; i < xy.length; i += 2 ) {
            coords[i / 2] = new Coordinate(xy[i], xy[i + 1]);
        }
        if (xy[0] != xy[xy.length - 2] || xy[1] != xy[xy.length - 1]) {
            coords[length - 1] = coords[0];
        }
        return gf.createLinearRing(coords);
    }
}
TOP

Related Classes of org.locationtech.udig.style.advanced.utils.Drawing

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.