Java Code Examples for java.awt.geom.GeneralPath#getPathIterator()

The following examples show how to use java.awt.geom.GeneralPath#getPathIterator() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: FontState.java    From ttt with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private String getGlyphPath(FontKey key, GeneralPath p, double advance) {
    StringBuffer sb = new StringBuffer();
    double size = key.size.getHeight();
    double s = size / this.upem;
    AffineTransform ctm = AffineTransform.getScaleInstance(s, -s);
    double[] coordinates = new double[6];
    for (PathIterator pi = p.getPathIterator(ctm); !pi.isDone(); pi.next()) {
        int op = pi.currentSegment(coordinates);
        if (op == PathIterator.SEG_CLOSE) {
            sb.append("Z ");
        } else if (op == PathIterator.SEG_CUBICTO) {
            sb.append("C ");
            appendCoordinates(sb, coordinates, 6);
        } else if (op == PathIterator.SEG_LINETO) {
            sb.append("L ");
            appendCoordinates(sb, coordinates, 2);
        } else if (op == PathIterator.SEG_MOVETO) {
            sb.append("M ");
            appendCoordinates(sb, coordinates, 2);
        } else if (op == PathIterator.SEG_QUADTO) {
            sb.append("Q ");
            appendCoordinates(sb, coordinates, 4);
        } else {
        }
    }
    return sb.toString().trim();
}
 
Example 2
Source File: Cardumen_0082_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Converts a path from Java2D space to data space.
 *
 * @param path  the path (<code>null</code> not permitted).
 * @param dataArea  the data area.
 * @param dataset  the dataset which can be used to find the appropriate
 *         axes.
 *
 * @return A path in data space.
 */
private GeneralPath convertToDataSpace(GeneralPath path,
        Rectangle2D dataArea, XYDataset dataset) {
    GeneralPath result = new GeneralPath(path.getWindingRule());
    int datasetIndex = indexOf(dataset);
    ValueAxis xAxis = getDomainAxisForDataset(datasetIndex);
    ValueAxis yAxis = getRangeAxisForDataset(datasetIndex);
    RectangleEdge xAxisEdge = getDomainAxisEdge();
    RectangleEdge yAxisEdge = getRangeAxisEdge();
    double[] coords = new double[6];
    PathIterator iterator = path.getPathIterator(null);
    while (!iterator.isDone()) {
        int segType = iterator.currentSegment(coords);
        double xx = xAxis.java2DToValue(coords[0], dataArea, xAxisEdge);
        double yy = yAxis.java2DToValue(coords[1], dataArea, yAxisEdge);
        if (segType == PathIterator.SEG_MOVETO) {
            result.moveTo((float) xx, (float) yy);
        }
        else if (segType == PathIterator.SEG_LINETO) {
            result.lineTo((float) xx, (float) yy);
        }
        else if (segType == PathIterator.SEG_CLOSE) {
            result.closePath();
        }
        iterator.next();
    }
    return result;
}
 
Example 3
Source File: Cardumen_009_t.java    From coming with MIT License 5 votes vote down vote up
/**
 * Converts a path from Java2D space to data space.
 *
 * @param path  the path (<code>null</code> not permitted).
 * @param dataArea  the data area.
 * @param dataset  the dataset which can be used to find the appropriate
 *         axes.
 *
 * @return A path in data space.
 */
private GeneralPath convertToDataSpace(GeneralPath path,
        Rectangle2D dataArea, XYDataset dataset) {
    GeneralPath result = new GeneralPath(path.getWindingRule());
    int datasetIndex = indexOf(dataset);
    ValueAxis xAxis = getDomainAxisForDataset(datasetIndex);
    ValueAxis yAxis = getRangeAxisForDataset(datasetIndex);
    RectangleEdge xAxisEdge = getDomainAxisEdge();
    RectangleEdge yAxisEdge = getRangeAxisEdge();
    double[] coords = new double[6];
    PathIterator iterator = path.getPathIterator(null);
    while (!iterator.isDone()) {
        int segType = iterator.currentSegment(coords);
        double xx = xAxis.java2DToValue(coords[0], dataArea, xAxisEdge);
        double yy = yAxis.java2DToValue(coords[1], dataArea, yAxisEdge);
        if (segType == PathIterator.SEG_MOVETO) {
            result.moveTo((float) xx, (float) yy);
        }
        else if (segType == PathIterator.SEG_LINETO) {
            result.lineTo((float) xx, (float) yy);
        }
        else if (segType == PathIterator.SEG_CLOSE) {
            result.closePath();
        }
        iterator.next();
    }
    return result;
}
 
Example 4
Source File: StandardGlyphVector.java    From jdk8u-jdk with GNU General Public License v2.0 5 votes vote down vote up
void appendGlyphOutline(int glyphID, GeneralPath result, float x, float y) {
    // !!! fontStrike needs a method for this.  For that matter, GeneralPath does.
    GeneralPath gp = null;
    if (sgv.invdtx == null) {
        gp = strike.getGlyphOutline(glyphID, x + dx, y + dy);
    } else {
        gp = strike.getGlyphOutline(glyphID, 0, 0);
        gp.transform(sgv.invdtx);
        gp.transform(AffineTransform.getTranslateInstance(x + dx, y + dy));
    }
    PathIterator iterator = gp.getPathIterator(null);
    result.append(iterator, false);
}
 
Example 5
Source File: StandardGlyphVector.java    From jdk8u_jdk with GNU General Public License v2.0 5 votes vote down vote up
void appendGlyphOutline(int glyphID, GeneralPath result, float x, float y) {
    // !!! fontStrike needs a method for this.  For that matter, GeneralPath does.
    GeneralPath gp = null;
    if (sgv.invdtx == null) {
        gp = strike.getGlyphOutline(glyphID, x + dx, y + dy);
    } else {
        gp = strike.getGlyphOutline(glyphID, 0, 0);
        gp.transform(sgv.invdtx);
        gp.transform(AffineTransform.getTranslateInstance(x + dx, y + dy));
    }
    PathIterator iterator = gp.getPathIterator(null);
    result.append(iterator, false);
}
 
Example 6
Source File: ClipperDemo.java    From pumpernickel with MIT License 5 votes vote down vote up
@Override
protected void paintComponent(Graphics g) {
	int min = Math.min(getWidth(), getHeight());

	super.paintComponent(g);
	Graphics2D g2 = (Graphics2D) g.create();
	g2.transform(TransformUtils.createAffineTransform(new Rectangle(0,
			0, 300, 300), new Rectangle(getWidth() / 2 - min / 2,
			getHeight() / 2 - min / 2, min, min)));
	g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
			RenderingHints.VALUE_ANTIALIAS_ON);
	int shapeIndex = ((Number) shapeIndexSpinner.getValue()).intValue() - 1;
	int type = typeComboBox.getSelectedIndex();
	GeneralPath s = p[type][shapeIndex];
	g2.setColor(Color.white);
	g2.fillRect(0, 0, 300, 300);
	g2.setColor(Color.blue);
	g2.fill(s);
	GeneralPath s2 = Clipper.clipToRect(s, null, r);
	g2.setColor(new Color(0, 255, 0, 120));
	g2.fill(s2);
	PathIterator i = s.getPathIterator(null);
	float[] f2 = new float[6];
	g.setColor(Color.red);
	while (i.isDone() == false) {
		int k = i.currentSegment(f2);
		if (k == PathIterator.SEG_MOVETO) {
			g2.fill(new Ellipse2D.Float(f2[0] - 2, f2[1] - 2, 4, 4));
		} else if (k == PathIterator.SEG_LINETO) {
			g2.draw(new Ellipse2D.Float(f2[0] - 2, f2[1] - 2, 4, 4));
		} else if (k == PathIterator.SEG_QUADTO) {
			g2.draw(new Ellipse2D.Float(f2[2] - 2, f2[3] - 2, 4, 4));
		} else if (k == PathIterator.SEG_CUBICTO) {
			g2.draw(new Ellipse2D.Float(f2[4] - 2, f2[5] - 2, 4, 4));
		}
		i.next();
	}
	g2.setColor(new Color(0, 0, 0, 120));
	g2.draw(r);
}
 
Example 7
Source File: StandardGlyphVector.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
void appendGlyphOutline(int glyphID, GeneralPath result, float x, float y) {
    // !!! fontStrike needs a method for this.  For that matter, GeneralPath does.
    GeneralPath gp = null;
    if (sgv.invdtx == null) {
        gp = strike.getGlyphOutline(glyphID, x + dx, y + dy);
    } else {
        gp = strike.getGlyphOutline(glyphID, 0, 0);
        gp.transform(sgv.invdtx);
        gp.transform(AffineTransform.getTranslateInstance(x + dx, y + dy));
    }
    PathIterator iterator = gp.getPathIterator(null);
    result.append(iterator, false);
}
 
Example 8
Source File: StandardGlyphVector.java    From openjdk-8-source with GNU General Public License v2.0 5 votes vote down vote up
void appendGlyphOutline(int glyphID, GeneralPath result, float x, float y) {
    // !!! fontStrike needs a method for this.  For that matter, GeneralPath does.
    GeneralPath gp = null;
    if (sgv.invdtx == null) {
        gp = strike.getGlyphOutline(glyphID, x + dx, y + dy);
    } else {
        gp = strike.getGlyphOutline(glyphID, 0, 0);
        gp.transform(sgv.invdtx);
        gp.transform(AffineTransform.getTranslateInstance(x + dx, y + dy));
    }
    PathIterator iterator = gp.getPathIterator(null);
    result.append(iterator, false);
}
 
Example 9
Source File: Elixir_001_s.java    From coming with MIT License 5 votes vote down vote up
/**
 * Tests two polygons for equality.  If both are <code>null</code> this
 * method returns <code>true</code>.
 *
 * @param p1  path 1 (<code>null</code> permitted).
 * @param p2  path 2 (<code>null</code> permitted).
 *
 * @return A boolean.
 */
public static boolean equal(GeneralPath p1, GeneralPath p2) {
    if (p1 == null) {
        return (p2 == null);
    }
    if (p2 == null) {
        return false;
    }
    if (p1.getWindingRule() != p2.getWindingRule()) {
        return false;
    }
    PathIterator iterator1 = p1.getPathIterator(null);
    PathIterator iterator2 = p1.getPathIterator(null);
    double[] d1 = new double[6];
    double[] d2 = new double[6];
    boolean done = iterator1.isDone() && iterator2.isDone();
    while (!done) {
        if (iterator1.isDone() != iterator2.isDone()) {
            return false;
        }
        int seg1 = iterator1.currentSegment(d1);
        int seg2 = iterator2.currentSegment(d2);
        if (seg1 != seg2) {
            return false;
        }
        if (!Arrays.equals(d1, d2)) {
            return false;
        }
        iterator1.next();
        iterator2.next();
        done = iterator1.isDone() && iterator2.isDone();
    }
    return true;
}
 
Example 10
Source File: PathTravel.java    From han3_ji7_tsoo1_kian3 with GNU Affero General Public License v3.0 5 votes vote down vote up
/**
 * 循訪路徑。
 * 
 * @param generalPath
 *            欲循訪的路徑
 */
public void travelOn(GeneralPath generalPath)
{
	double[] controlPoint = new double[6];
	for (PathIterator pathIterator = generalPath.getPathIterator(null); !pathIterator
			.isDone(); pathIterator.next())
	{
		int type = pathIterator.currentSegment(controlPoint);

		switch (type)
		{
		case PathIterator.SEG_MOVETO:
			pathAction.doActionOnMoveTo(controlPoint);
			break;
		case PathIterator.SEG_LINETO:
			pathAction.doActionOnLineTo(controlPoint);
			break;
		case PathIterator.SEG_QUADTO:
			pathAction.doActionOnQuadTo(controlPoint);
			break;
		case PathIterator.SEG_CUBICTO:
			pathAction.doActionOnCubicTo(controlPoint);
			break;
		case PathIterator.SEG_CLOSE:
			pathAction.doActionOnCloseTo(controlPoint);
			break;
		}
	}
}
 
Example 11
Source File: ShapeUtilities.java    From ccu-historian with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Tests two polygons for equality.  If both are <code>null</code> this
 * method returns <code>true</code>.
 *
 * @param p1  path 1 (<code>null</code> permitted).
 * @param p2  path 2 (<code>null</code> permitted).
 *
 * @return A boolean.
 */
public static boolean equal(final GeneralPath p1, final GeneralPath p2) {
    if (p1 == null) {
        return (p2 == null);
    }
    if (p2 == null) {
        return false;
    }
    if (p1.getWindingRule() != p2.getWindingRule()) {
        return false;
    }
    PathIterator iterator1 = p1.getPathIterator(null);
    PathIterator iterator2 = p2.getPathIterator(null);
    double[] d1 = new double[6];
    double[] d2 = new double[6];
    boolean done = iterator1.isDone() && iterator2.isDone();
    while (!done) {
        if (iterator1.isDone() != iterator2.isDone()) {
            return false;
        }
        int seg1 = iterator1.currentSegment(d1);
        int seg2 = iterator2.currentSegment(d2);
        if (seg1 != seg2) {
            return false;
        }
        if (!Arrays.equals(d1, d2)) {
            return false;
        }
        iterator1.next();
        iterator2.next();
        done = iterator1.isDone() && iterator2.isDone();
    }
    return true;
}
 
Example 12
Source File: StandardGlyphVector.java    From jdk8u-jdk with GNU General Public License v2.0 5 votes vote down vote up
void appendGlyphOutline(int glyphID, GeneralPath result, float x, float y) {
    // !!! fontStrike needs a method for this.  For that matter, GeneralPath does.
    GeneralPath gp = null;
    if (sgv.invdtx == null) {
        gp = strike.getGlyphOutline(glyphID, x + dx, y + dy);
    } else {
        gp = strike.getGlyphOutline(glyphID, 0, 0);
        gp.transform(sgv.invdtx);
        gp.transform(AffineTransform.getTranslateInstance(x + dx, y + dy));
    }
    PathIterator iterator = gp.getPathIterator(null);
    result.append(iterator, false);
}
 
Example 13
Source File: ShapeUtilities.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Tests two polygons for equality.  If both are <code>null</code> this
 * method returns <code>true</code>.
 *
 * @param p1  path 1 (<code>null</code> permitted).
 * @param p2  path 2 (<code>null</code> permitted).
 *
 * @return A boolean.
 */
public static boolean equal(GeneralPath p1, GeneralPath p2) {
    if (p1 == null) {
        return (p2 == null);
    }
    if (p2 == null) {
        return false;
    }
    if (p1.getWindingRule() != p2.getWindingRule()) {
        return false;
    }
    PathIterator iterator1 = p1.getPathIterator(null);
    PathIterator iterator2 = p1.getPathIterator(null);
    double[] d1 = new double[6];
    double[] d2 = new double[6];
    boolean done = iterator1.isDone() && iterator2.isDone();
    while (!done) {
        if (iterator1.isDone() != iterator2.isDone()) {
            return false;
        }
        int seg1 = iterator1.currentSegment(d1);
        int seg2 = iterator2.currentSegment(d2);
        if (seg1 != seg2) {
            return false;
        }
        if (!Arrays.equals(d1, d2)) {
            return false;
        }
        iterator1.next();
        iterator2.next();
        done = iterator1.isDone() && iterator2.isDone();
    }
    return true;
}
 
Example 14
Source File: StandardGlyphVector.java    From Bytecoder with Apache License 2.0 5 votes vote down vote up
void appendGlyphOutline(int glyphID, GeneralPath result, float x, float y) {
    // !!! fontStrike needs a method for this.  For that matter, GeneralPath does.
    GeneralPath gp = null;
    if (sgv.invdtx == null) {
        gp = strike.getGlyphOutline(glyphID, x + dx, y + dy);
    } else {
        gp = strike.getGlyphOutline(glyphID, 0, 0);
        gp.transform(sgv.invdtx);
        gp.transform(AffineTransform.getTranslateInstance(x + dx, y + dy));
    }
    PathIterator iterator = gp.getPathIterator(null);
    result.append(iterator, false);
}
 
Example 15
Source File: ShapeUtilities.java    From astor with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Tests two polygons for equality.  If both are <code>null</code> this
 * method returns <code>true</code>.
 *
 * @param p1  path 1 (<code>null</code> permitted).
 * @param p2  path 2 (<code>null</code> permitted).
 *
 * @return A boolean.
 */
public static boolean equal(GeneralPath p1, GeneralPath p2) {
    if (p1 == null) {
        return (p2 == null);
    }
    if (p2 == null) {
        return false;
    }
    if (p1.getWindingRule() != p2.getWindingRule()) {
        return false;
    }
    PathIterator iterator1 = p1.getPathIterator(null);
    PathIterator iterator2 = p2.getPathIterator(null);
    double[] d1 = new double[6];
    double[] d2 = new double[6];
    boolean done = iterator1.isDone() && iterator2.isDone();
    while (!done) {
        if (iterator1.isDone() != iterator2.isDone()) {
            return false;
        }
        int seg1 = iterator1.currentSegment(d1);
        int seg2 = iterator2.currentSegment(d2);
        if (seg1 != seg2) {
            return false;
        }
        if (!Arrays.equals(d1, d2)) {
            return false;
        }
        iterator1.next();
        iterator2.next();
        done = iterator1.isDone() && iterator2.isDone();
    }
    return true;
}
 
Example 16
Source File: StandardGlyphVector.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
void appendGlyphOutline(int glyphID, GeneralPath result, float x, float y) {
    // !!! fontStrike needs a method for this.  For that matter, GeneralPath does.
    GeneralPath gp = null;
    if (sgv.invdtx == null) {
        gp = strike.getGlyphOutline(glyphID, x + dx, y + dy);
    } else {
        gp = strike.getGlyphOutline(glyphID, 0, 0);
        gp.transform(sgv.invdtx);
        gp.transform(AffineTransform.getTranslateInstance(x + dx, y + dy));
    }
    PathIterator iterator = gp.getPathIterator(null);
    result.append(iterator, false);
}
 
Example 17
Source File: PDTextAppearanceHandler.java    From gcs with Mozilla Public License 2.0 4 votes vote down vote up
private void addPath(final PDAppearanceContentStream contentStream, GeneralPath path) throws IOException
{
    double curX = 0;
    double curY = 0;
    PathIterator it = path.getPathIterator(new AffineTransform());
    double[] coords = new double[6];
    while (!it.isDone())
    {
        int type = it.currentSegment(coords);
        switch (type)
        {
            case PathIterator.SEG_CLOSE:
                contentStream.closePath();
                break;
            case PathIterator.SEG_CUBICTO:
                contentStream.curveTo((float) coords[0], (float) coords[1], (float) coords[2],
                                      (float) coords[3], (float) coords[4], (float) coords[5]);
                curX = coords[4];
                curY = coords[5];
                break;
            case PathIterator.SEG_QUADTO:
                // Convert quadratic Bézier curve to cubic
                // https://fontforge.github.io/bezier.html
                // CP1 = QP0 + 2/3 *(QP1-QP0)
                // CP2 = QP2 + 2/3 *(QP1-QP2)
                double cp1x = curX + 2d / 3d * (coords[0] - curX);
                double cp1y = curY + 2d / 3d * (coords[1] - curY);
                double cp2x = coords[2] + 2d / 3d * (coords[0] - coords[2]);
                double cp2y = coords[3] + 2d / 3d * (coords[1] - coords[3]);
                contentStream.curveTo((float) cp1x, (float) cp1y,
                                      (float) cp2x, (float) cp2y,
                                      (float) coords[2], (float) coords[3]);
                curX = coords[2];
                curY = coords[3];
                break;
            case PathIterator.SEG_LINETO:
                contentStream.lineTo((float) coords[0], (float) coords[1]);
                curX = coords[0];
                curY = coords[1];
                break;
            case PathIterator.SEG_MOVETO:
                contentStream.moveTo((float) coords[0], (float) coords[1]);
                curX = coords[0];
                curY = coords[1];
                break;
            default:
                break;
        }
        it.next();
    }
}
 
Example 18
Source File: PageDrawer.java    From sambox with Apache License 2.0 4 votes vote down vote up
/**
 * Returns true if the given path is rectangular.
 */
private boolean isRectangular(GeneralPath path)
{
    PathIterator iter = path.getPathIterator(null);
    double[] coords = new double[6];
    int count = 0;
    int[] xs = new int[4];
    int[] ys = new int[4];
    while (!iter.isDone())
    {
        switch (iter.currentSegment(coords))
        {
        case PathIterator.SEG_MOVETO:
            if (count == 0)
            {
                xs[count] = (int) Math.floor(coords[0]);
                ys[count] = (int) Math.floor(coords[1]);
            }
            else
            {
                return false;
            }
            count++;
            break;

        case PathIterator.SEG_LINETO:
            if (count < 4)
            {
                xs[count] = (int) Math.floor(coords[0]);
                ys[count] = (int) Math.floor(coords[1]);
            }
            else
            {
                return false;
            }
            count++;
            break;

        case PathIterator.SEG_CUBICTO:
            return false;

        case PathIterator.SEG_CLOSE:
            break;
        default:
            break;
        }
        iter.next();
    }

    if (count == 4)
    {
        return xs[0] == xs[1] || xs[0] == xs[2] || ys[0] == ys[1] || ys[0] == ys[3];
    }
    return false;
}
 
Example 19
Source File: SymbolDraw.java    From mil-sym-java with Apache License 2.0 4 votes vote down vote up
/**
 * traverse a General path and see how it's made.
 * @param path
 * @return
 */
public static String GeneralPathToString(GeneralPath path)
{
    StringBuilder sb = new StringBuilder();
    PathIterator itr = null;
    double[] coords = new double[6];
    int pathSegmentType = 0;
    String strPathSegmentType = "";
    try
    {
        itr = path.getPathIterator(null);
        while(itr.isDone()==false)
        {
            //itr.next();
            pathSegmentType = itr.currentSegment(coords);
            if(pathSegmentType == itr.SEG_MOVETO)
                sb.append("SEG_MOVETO");
            else if(pathSegmentType == itr.SEG_CUBICTO)
                sb.append("SEG_CUBICTO");
            else if(pathSegmentType == itr.SEG_LINETO)
                sb.append("SEG_LINETO");
            else if(pathSegmentType == itr.SEG_QUADTO)
                sb.append("SEG_QUADTO");
            else if(pathSegmentType == itr.SEG_CLOSE)
                sb.append("SEG_CLOSE");

            sb.append(": ");

            if(pathSegmentType == itr.SEG_MOVETO)
                sb.append(String.valueOf(coords[0]) + ", " + String.valueOf(coords[1]));
            else if(pathSegmentType == itr.SEG_CUBICTO)
                sb.append(String.valueOf(coords[0]) + ", " + String.valueOf(coords[1]));
            else if(pathSegmentType == itr.SEG_LINETO)
                sb.append(String.valueOf(coords[0]) + ", " + String.valueOf(coords[1]));
            else if(pathSegmentType == itr.SEG_QUADTO)
                sb.append(String.valueOf(coords[0]) + ", " + String.valueOf(coords[1]));
            else if(pathSegmentType == itr.SEG_CLOSE)
                sb.append(String.valueOf(coords[0]) + ", " + String.valueOf(coords[1]));

            sb.append('\n');
            
            coords = new double[6];
            itr.next();

        }

    }
    catch(Exception exc)
    {

    }

    return sb.toString();
}
 
Example 20
Source File: DefaultProductLayer.java    From snap-desktop with GNU General Public License v3.0 4 votes vote down vote up
private void addOutline(final Product product) {

        final int step = Math.max(16, (product.getSceneRasterWidth() + product.getSceneRasterHeight()) / 250);
        final GeneralPath[] boundaryPaths = ProductUtils.createGeoBoundaryPaths(product, null, step);

        final Polyline[] polyLineList = new Polyline[boundaryPaths.length];
        int i = 0;
        int numPoints = 0;
        float centreLat = 0;
        float centreLon = 0;

        for (GeneralPath boundaryPath : boundaryPaths) {
            final PathIterator it = boundaryPath.getPathIterator(null);
            final float[] floats = new float[2];
            final List<Position> positions = new ArrayList<>(4);

            it.currentSegment(floats);
            final Position firstPosition = new Position(Angle.fromDegreesLatitude(floats[1]),
                                                        Angle.fromDegreesLongitude(floats[0]), 0.0);
            positions.add(firstPosition);
            centreLat += floats[1];
            centreLon += floats[0];
            it.next();
            numPoints++;

            while (!it.isDone()) {
                it.currentSegment(floats);
                positions.add(new Position(Angle.fromDegreesLatitude(floats[1]),
                                           Angle.fromDegreesLongitude(floats[0]), 0.0));

                centreLat += floats[1];
                centreLon += floats[0];
                it.next();
                numPoints++;
            }
            // close the loop
            positions.add(firstPosition);

            centreLat = centreLat / numPoints;
            centreLon = centreLon / numPoints;


            polyLineList[i] = new Polyline();
            polyLineList[i].setFollowTerrain(true);
            polyLineList[i].setPositions(positions);

            // ADDED
            //polyLineList[i].setColor(new Color(1f, 0f, 0f, 0.99f));
            //polyLineList[i].setLineWidth(10);

            addRenderable(polyLineList[i]);
            ++i;
        }

        Position centrePos = new Position(Angle.fromDegreesLatitude(centreLat), Angle.fromDegreesLongitude(centreLon), 0.0);

        PointPlacemark ppm = getLabelPlacemark(centrePos, String.valueOf(product.getRefNo()));
        ppm.setAltitudeMode(WorldWind.CLAMP_TO_GROUND);
        ppm.setEnableDecluttering(true);

        addRenderable(ppm);

        outlineTable.put(getUniqueName(product), polyLineList);
        labelTable.put(getUniqueName(product), ppm);
    }