Package gistoolkit.display.renderer

Source Code of gistoolkit.display.renderer.PolygonRenderer$ScreenPoint

/*
*    GISToolkit - Geographical Information System Toolkit
*    (C) 2002, Ithaqua Enterprises Inc.
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation;
*    version 2.1 of the License.
*
*    This library is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*    Lesser General Public License for more details.
*
*    You should have received a copy of the GNU Lesser General Public
*    License along with this library; if not, write to the Free Software
*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
*/

package gistoolkit.display.renderer;

import java.util.Properties;
import java.util.Vector;
import java.awt.Graphics;
import java.awt.Graphics2D;
import gistoolkit.common.*;
import gistoolkit.features.*;
import gistoolkit.display.*;

/**
* Created to render shapes in a single colors, default colors are black border, no fill.
*/
public class PolygonRenderer extends SimpleRenderer{
    /** The name for this renderer, always returns "Polygon Renderer" */
    public String getRendererName(){ return "Polygon Renderer";}
   
    private int[] myXs = new int[0];
    private int[] myYs = new int[0];
   
    /**
     * Class for holding the screen points
     */
    private class ScreenPoint{
        int x;
        int y;
       
        public ScreenPoint(){
        }
       
        public ScreenPoint(int inX, int inY){
            x = inX;
            y = inY;
        }
       
        boolean equals(ScreenPoint inScreenPoint){
            if (inScreenPoint.x != x) return false;
            if (inScreenPoint.y != y) return false;
            return true;
        }
    }
   
    /**
     * MonoShader constructor comment.
     */
    public PolygonRenderer() {
        super();
    }
   
    /**
     * Convert an array of points from World Coordinates to Screen coordinates.
     */
    private ScreenPoint[] convertToScreen(double[] inX, double[] inY, Converter inConverter){
        if (inX == null) return new ScreenPoint[0];
        if (inX.length  == 0) return new ScreenPoint[0];
       
        // convert the ponts
        Vector tempScreenVector = new Vector(inX.length);
        ScreenPoint tempScreenPoint = null;
        ScreenPoint tempPreviousScreenPoint = null;
        for (int i=0; i<inX.length; i++){
            tempScreenPoint = new ScreenPoint();
            tempScreenPoint.x = inConverter.toScreenX(inX[i]);
            tempScreenPoint.y = inConverter.toScreenY(inY[i]);
           
            if ((tempPreviousScreenPoint == null) || (!tempPreviousScreenPoint.equals(tempScreenPoint))){
                tempScreenVector.addElement(tempScreenPoint);
                tempPreviousScreenPoint = tempScreenPoint;
            }
           
        }
       
        if (tempScreenVector.size() < 3){ return null;}
       
        // test to enxure the shape is closed.
        if ( ((ScreenPoint)tempScreenVector.elementAt(0)).equals((ScreenPoint) tempScreenVector.elementAt(tempScreenVector.size()-1))){
            tempScreenVector.removeElementAt(tempScreenVector.size()-1);
        }
        ScreenPoint[] tempScreenPoints = new ScreenPoint[tempScreenVector.size()];
        tempScreenVector.copyInto(tempScreenPoints);
        return tempScreenPoints;
    }
   
    /**
     * Draws the Shapes
     */
    public boolean drawShape(Record inRecord, Graphics inGraphics, Converter inConverter, Shader inShader) {
        if (inRecord == null) return false;
        if (!(inRecord.getShape() instanceof Polygon))
            return false;
       
        Polygon tempPolygon = (Polygon) inRecord.getShape();
       
        // draw the posative shape
        LinearRing tempRing = tempPolygon.getPosativeRing();
        double[] tempXs = tempRing.getXCoordinates();
        double[] tempYs = tempRing.getYCoordinates();
        if (myXs.length < tempXs.length){
            myXs = new int[tempXs.length];
            myYs = new int[tempXs.length];
        }
        for (int i = 0; i < tempXs.length; i++) {
            myXs[i] = inConverter.toScreenX(tempXs[i]);
            myYs[i] = inConverter.toScreenY(tempYs[i]);
        }
       
        // call to graphics routine to fill the posative shape.
        Graphics tempGraphics = inShader.getFillGraphics(inGraphics, inRecord.getAttributes(), inRecord.getAttributeNames());
        if (tempGraphics != null) {
            if ((tempPolygon.getHoles() != null) && (tempPolygon.getHoles().length >0)){
                drawShapeWithHoles(inRecord, tempGraphics, inConverter, inShader);
            }
            else{
                tempGraphics.fillPolygon(myXs, myYs, tempXs.length);
            }
        }
       
        // call the graphics routine to draw the posative shape.'
        tempGraphics = inShader.getLineGraphics(inGraphics, inRecord.getAttributes(), inRecord.getAttributeNames());
        if (tempGraphics != null) {
            tempGraphics.drawPolygon(myXs, myYs, tempXs.length);
        }
       
        // draw the negative shapes
        LinearRing[] tempHoles = tempPolygon.getHoles();
        if (tempHoles != null) {
            for (int i = 0; i < tempHoles.length; i++) {
                tempRing = tempHoles[i];
                tempXs = tempRing.getXCoordinates();
                tempYs = tempRing.getYCoordinates();
                if (myXs.length < tempXs.length){
                    myXs = new int[tempXs.length];
                    myYs = new int[tempXs.length];
                }
                for (int j = 0; j < tempXs.length; j++) {
                    myXs[j] = inConverter.convertX(tempXs[j]);
                    myYs[j] = inConverter.convertY(tempYs[j]);
                }
               
                // call the graphics routine to draw the negative shape.
                if (tempGraphics != null) tempGraphics.drawPolygon(myXs, myYs, tempXs.length);
            }
        }
        return true;
    }
   
    /**
     * Draws the Shapes
     */
    public boolean drawShapeHighlight(Record inRecord, Graphics inGraphics, Converter inConverter, Shader inShader) {
        if (inRecord == null) return false;
        if (!(inRecord.getShape() instanceof Polygon))
            return false;
       
        Polygon tempPolygon = (Polygon) inRecord.getShape();
       
        // draw the posative shape
        LinearRing tempRing = tempPolygon.getPosativeRing();
        double[] tempDXs = tempRing.getXCoordinates();
        double[] tempDYs = tempRing.getYCoordinates();
        int[] tempXs = new int[tempDXs.length];
        int[] tempYs = new int[tempDYs.length];
        for (int i = 0; i < tempDXs.length; i++) {
            tempXs[i] = inConverter.toScreenX(tempDXs[i]);
            tempYs[i] = inConverter.toScreenY(tempDYs[i]);
        }
       
        // call the graphics routine to draw the posative shape.'
        Graphics tempGraphics = inShader.getLineHighlightGraphics(inGraphics, inRecord.getAttributes(), inRecord.getAttributeNames());
        if (tempGraphics != null) {
            tempGraphics.drawPolygon(tempXs, tempYs, tempDXs.length);
        }
       
        // draw the negative shapes
        LinearRing[] tempHoles = tempPolygon.getHoles();
        if (tempHoles != null) {
            for (int i = 0; i < tempHoles.length; i++) {
                tempRing = tempHoles[i];
                tempDXs = tempRing.getXCoordinates();
                tempDYs = tempRing.getYCoordinates();
                tempXs = new int[tempDXs.length];
                tempYs = new int[tempDYs.length];
                for (int j = 0; j < tempDXs.length; j++) {
                    tempXs[j] = inConverter.toScreenX(tempDXs[j]);
                    tempYs[j] = inConverter.toScreenY(tempDYs[j]);
                }
               
                // call the graphics routine to draw the negative shape.
                tempGraphics.drawPolygon(tempXs, tempYs, tempDXs.length);
            }
        }
        return true;
    }
   
    /**
     * Draws the Shapes
     */
    public boolean drawShapePoints(Record inRecord, Graphics inGraphics, Converter inConverter, Shader inShader) {
        if (inRecord == null) return false;
        if (!(inRecord.getShape() instanceof Polygon))
            return false;
       
        Polygon tempPolygon = (Polygon) inRecord.getShape();
       
        // draw the posative shape
        LinearRing tempRing = tempPolygon.getPosativeRing();
        double[] tempDXs = tempRing.getXCoordinates();
        double[] tempDYs = tempRing.getYCoordinates();
        int[] tempXs = new int[tempDXs.length];
        int[] tempYs = new int[tempDYs.length];
        for (int i = 0; i < tempDXs.length; i++) {
            tempXs[i] = inConverter.convertX(tempDXs[i]);
            tempYs[i] = inConverter.convertY(tempDYs[i]);
        }
       
        // call the graphics routine to draw the posative shape.'
        Graphics tempGraphics = inShader.getLabelHighlightGraphics(inGraphics, inRecord.getAttributes(), inRecord.getAttributeNames());
        if (tempGraphics != null) {
            for (int i=0; i<tempXs.length; i++){
                tempGraphics.drawOval(tempXs[i]-4, tempYs[i]-4, 8,8);
            }
        }
       
        // draw the negative shapes
        LinearRing[] tempHoles = tempPolygon.getHoles();
        if (tempHoles != null) {
            for (int i = 0; i < tempHoles.length; i++) {
                tempRing = tempHoles[i];
                tempDXs = tempRing.getXCoordinates();
                tempDYs = tempRing.getYCoordinates();
                tempXs = new int[tempDXs.length];
                tempYs = new int[tempDYs.length];
                for (int j = 0; j < tempDXs.length; j++) {
                    tempXs[j] = inConverter.convertX(tempDXs[j]);
                    tempYs[j] = inConverter.convertY(tempDYs[j]);
                }
               
                // call the graphics routine to draw the negative shape.
                for (int j=0; j<tempXs.length; j++){
                    tempGraphics.drawOval(tempXs[j]-4, tempYs[j]-4, 8,8);
                }
            }
        }
        return true;
    }
   
    /**
     * Draws the Shapes
     */
    private boolean drawShapeWithHoles(Record inRecord,  Graphics inGraphics, Converter inConverter, Shader inShader) {
        if (inRecord == null) return false;
        if (!(inRecord.getShape() instanceof Polygon))
            return false;
       
        Polygon tempPolygon = (Polygon) inRecord.getShape();
       
        // Create a shape to handle this case.
        java.awt.geom.GeneralPath tempPath = new java.awt.geom.GeneralPath(java.awt.geom.GeneralPath.WIND_EVEN_ODD);
       
        // convert the points to screen coordinates
        Vector tempRingVect = new Vector();
        ScreenPoint[] tempScreenPoints = null;
        LinearRing tempRing = tempPolygon.getPosativeRing();
        if (tempRing != null) {
            double[] tempDXs = tempRing.getXCoordinates();
            double[] tempDYs = tempRing.getYCoordinates();
            if (tempDXs != null) {
                tempScreenPoints = convertToScreen(tempDXs, tempDYs, inConverter);
                if ((tempScreenPoints != null) && (tempScreenPoints.length > 0)){
                    tempPath.moveTo(tempScreenPoints[0].x, tempScreenPoints[0].y);
                    for (int i=1; i<tempScreenPoints.length; i++){
                        tempPath.lineTo(tempScreenPoints[i].x, tempScreenPoints[i].y);
                    }
                    tempPath.closePath();
                    tempRingVect.addElement(tempScreenPoints);
                }
            }
        }
       
        // convert the holes to screen coordinates.
        LinearRing[] tempRings = tempPolygon.getHoles();
        if (tempRings != null) {
            for (int i = 0; i < tempRings.length; i++) {
                double[] tempDXs = tempRings[i].getXCoordinates();
                double[] tempDYs = tempRings[i].getYCoordinates();
                tempScreenPoints = convertToScreen(tempDXs, tempDYs, inConverter);
                if ((tempScreenPoints != null) && (tempScreenPoints.length > 0)){
                    tempPath.moveTo(tempScreenPoints[0].x, tempScreenPoints[0].y);
                    for (int j=1; j<tempScreenPoints.length; j++){
                        tempPath.lineTo(tempScreenPoints[j].x, tempScreenPoints[j].y);
                    }
                    tempPath.closePath();
                    tempRingVect.addElement(tempScreenPoints);
                }
            }
        }
        Graphics2D tempG2D = (Graphics2D) inGraphics;
        tempG2D.fill(tempPath);
        /*
        // Find the largest Y coordinate, and minimum X coordinate, the following routine
        // will scann from minX to MaxX finding intersections lower than the maximum Y.
        // it is important that the MaxY be higher than all the points in the shape.
        int tempMinX = inConverter.toScreenX(tempPolygon.getExtents().myTopX) - 1;
        int tempMaxX = inConverter.toScreenX(tempPolygon.getExtents().myBottomX);
        int tempMaxY = inConverter.toScreenY(tempPolygon.getExtents().myBottomY) + 1;
        int tempMinY = inConverter.toScreenY(tempPolygon.getExtents().myTopY);
        
        // loop through all lines on the screen
        for (int k = tempMinX; k <= tempMaxX; k++) {
        
            // loop through the rings finding the interssections
        
            // current values to check
            int x = k;
            int y = tempMaxY;
        
            // previous points
            Vector tempDrawPoints = new Vector();
        
            // loop through the points finding the crossings.
            for (int i = 0; i < tempRingVect.size(); i++) {
        
                // check all the rings
                tempScreenPoints = (ScreenPoint[]) tempRingVect.elementAt(i);
                for (int j = 0; j < tempScreenPoints.length; j++) {
        
                    // this algorythm depends on three points
                    int prevPoint = j - 1;
                    if (prevPoint < 0)
                        prevPoint = tempScreenPoints.length - 1;
        
                    int nextPoint = j+1;
                    if (nextPoint == tempScreenPoints.length){
                        nextPoint = 0;
                    }
        
                    int x0 = tempScreenPoints[prevPoint].x;
                    int y0 = tempScreenPoints[prevPoint].y;
                    int x1 = tempScreenPoints[j].x;
                    int y1 = tempScreenPoints[j].y;
                    int x2 = tempScreenPoints[nextPoint].x;
                    int y2 = tempScreenPoints[nextPoint].y;
        
                    // determine if the points cross
                    double cy = 0;
                    if (((x1 < x) && (x < x2)) || ((x1 > x) && (x > x2))) {
                        double t = ((double) (x - x2)) / ((double) (x1 - x2));
                        cy = t * y1 + (1 - t) * y2;
                        if (y > cy) {
                            tempDrawPoints.addElement(new ScreenPoint(x, (int) cy));
                        }
                    }
        
                    // check for a ray passing directly through a point.
                    if (x1 == x) {
                        if (((x0 < x) && (x2 >= x)) || ((x0 >= x) && (x2 < x))) {
                            tempDrawPoints.addElement(new ScreenPoint(x, y1));
                        }
                    }
                }
            }
        
            // order the points by their y axis
            for (int i = 0; i < tempDrawPoints.size(); i++) {
                ScreenPoint sc1 = (ScreenPoint) tempDrawPoints.elementAt(i);
                for (int j = i+1; j < tempDrawPoints.size(); j++) {
                    ScreenPoint sc2 = (ScreenPoint) tempDrawPoints.elementAt(j);
                    if (sc1.y > sc2.y) {
                        tempDrawPoints.setElementAt(sc2, i);
                        tempDrawPoints.setElementAt(sc1, j);
                        sc1 = sc2;
                    }
                }
            }
        
            // draw the points
            for (int i = 0; i < tempDrawPoints.size()-1; i+=2) {
                inGraphics.drawLine(
                ((ScreenPoint) tempDrawPoints.elementAt(i)).x,
                ((ScreenPoint) tempDrawPoints.elementAt(i)).y,
                ((ScreenPoint) tempDrawPoints.elementAt(i + 1)).x,
                ((ScreenPoint) tempDrawPoints.elementAt(i + 1)).y);
            }
        
        }
         */
        return true;
    }
   
    /**
     * Read the properties for the initialization of the rendere from the properties sent in.
     */
    public void load(Properties inProperties) throws Exception {
    }
   
    /** Get the configuration information for this renderer  */
    public Node getNode() {
        return null;
    }
   
    /** Set the configuration information for this renderer  */
    public void setNode(Node inNode) throws Exception {
    }
   
    /** For display in lists and such. */
    public String toString(){
        return "Polygon Renderer";
    }
}
TOP

Related Classes of gistoolkit.display.renderer.PolygonRenderer$ScreenPoint

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.