Package org.locationtech.udig.printing.ui.pdf

Source Code of org.locationtech.udig.printing.ui.pdf.AntiqueGridMapGraphic

/*
*    uDig - User Friendly Desktop Internet GIS client
*    http://udig.refractions.net
*    (C) 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.printing.ui.pdf;

import java.awt.Color;
import java.awt.Font;
import java.awt.Point;
import java.awt.geom.AffineTransform;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.locationtech.udig.mapgraphic.MapGraphic;
import org.locationtech.udig.mapgraphic.MapGraphicContext;
import org.locationtech.udig.mapgraphic.MapGraphicPlugin;
import org.locationtech.udig.mapgraphic.grid.GridStyle;
import org.locationtech.udig.mapgraphic.internal.Messages;
import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.ui.graphics.ViewportGraphics;

import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
/**
*
* A grid that labels grid lines based on the current CRS using an
* "antique" style
* <p>
*
* </p>
* @author brocka
* @since 1.1.0
*/
public class AntiqueGridMapGraphic implements MapGraphic {

    private static int EDGE_WIDTH = 13;
    private static int LABEL_TEXT_BUFFER = 2;
    private static int TICK_WIDTH = 11;
   
    public void draw( MapGraphicContext context ) {

        Color gridColor = Color.black;
        Font font = new Font("Times", Font.PLAIN, 7);
       
        Envelope bounds = context.getViewportModel().getBounds();
        List<Double>[] gridLines = chooseGridLines(bounds);
      
        ViewportGraphics graphics = context.getGraphics();
        int mapPixelWidth = context.getMapDisplay().getWidth();
        int mapPixelHeight = context.getMapDisplay().getHeight();
        graphics.setColor(gridColor);
       
        List<Double> xCoords = gridLines[0];
        List<Double> yCoords = gridLines[1];
       
        //draw grid "crosses" and ticks
        for (int i = 0; i < xCoords.size(); i++) {
            double x = xCoords.get(i).doubleValue();

            for (int j = 0; j < yCoords.size() ; j++) {
               
                double y = yCoords.get(j).doubleValue();
                Coordinate thisCoord = new Coordinate(x, y);
            
                Point thisPixel = context.worldToPixel(thisCoord);

                //ticks along left and right
                if (i == 0) {
                    //draw left-most ticks
                    graphics.drawLine(EDGE_WIDTH,
                            thisPixel.y,
                            EDGE_WIDTH + TICK_WIDTH,
                            thisPixel.y);
                   
                    //draw right-most ticks
                    graphics.drawLine(mapPixelWidth - EDGE_WIDTH,
                            thisPixel.y,
                            mapPixelWidth - EDGE_WIDTH - TICK_WIDTH,
                            thisPixel.y);
                   
                }

               
                //ticks along top and bottom
                if (j == 0) {
                    //draw top-most ticks
                    graphics.drawLine(thisPixel.x,
                            EDGE_WIDTH,
                            thisPixel.x,
                            EDGE_WIDTH + TICK_WIDTH);
                   
                    //draw bottom-most ticks
                    graphics.drawLine(thisPixel.x,
                            mapPixelHeight - EDGE_WIDTH,
                            thisPixel.x,
                            mapPixelHeight - EDGE_WIDTH - TICK_WIDTH);
                   
                }

                //draw crosses
                graphics.setColor(Color.YELLOW);
                graphics.drawLine(thisPixel.x - TICK_WIDTH/2,
                        thisPixel.y,
                        thisPixel.x + TICK_WIDTH/2,
                        thisPixel.y);
               
                graphics.drawLine(thisPixel.x,
                        thisPixel.y - TICK_WIDTH/2,
                        thisPixel.x,
                        thisPixel.y + TICK_WIDTH/2);
            }
        } //end crosses and ticks
       
        //top border
        graphics.setColor(Color.white);
        graphics.fillRect(0,
                0,
                mapPixelWidth,
                EDGE_WIDTH);
        //right border
        graphics.fillRect(mapPixelWidth - EDGE_WIDTH,
                0,
                EDGE_WIDTH,
                mapPixelHeight);
        //bottom border
        graphics.fillRect(0,
                          mapPixelHeight - EDGE_WIDTH,
                          mapPixelWidth,
                          EDGE_WIDTH);
        //left border
        graphics.fillRect(0,
                          0,
                          EDGE_WIDTH,
                          mapPixelHeight);
       
        //top-left corner
        graphics.setColor(Color.white);
        graphics.fillRect(0,
                0,
                EDGE_WIDTH*2,
                EDGE_WIDTH*2);
        graphics.setColor(Color.black);
        graphics.fillOval(EDGE_WIDTH/2+1, EDGE_WIDTH/2+1, EDGE_WIDTH, EDGE_WIDTH);
        graphics.drawRect(0,
                0,
                EDGE_WIDTH*2,
                EDGE_WIDTH*2);
       
        //top-right corner
        AffineTransform origTrans = graphics.getTransform();
        AffineTransform topRightTrans = graphics.getTransform();
        topRightTrans.translate(mapPixelWidth - EDGE_WIDTH*2, 0);
        graphics.setTransform(topRightTrans);
        graphics.setColor(Color.white);
        graphics.fillRect(0,
                0,
                EDGE_WIDTH*2,
                EDGE_WIDTH*2);
        graphics.setColor(Color.black);
        graphics.fillOval(EDGE_WIDTH/2+1, EDGE_WIDTH/2+1, EDGE_WIDTH, EDGE_WIDTH);
        graphics.drawRect(0,
                0,
                EDGE_WIDTH*2,
                EDGE_WIDTH*2);
       
        //bottom-right corner
        AffineTransform bottomRightTrans = (AffineTransform)origTrans.clone();
        bottomRightTrans.translate(mapPixelWidth - EDGE_WIDTH*2, mapPixelHeight - EDGE_WIDTH*2);
        graphics.setTransform(bottomRightTrans);
        graphics.setColor(Color.white);
        graphics.fillRect(0,
                0,
                EDGE_WIDTH*2,
                EDGE_WIDTH*2);
        graphics.setColor(Color.black);
        graphics.fillOval(EDGE_WIDTH/2+1, EDGE_WIDTH/2+1, EDGE_WIDTH, EDGE_WIDTH);
        graphics.drawRect(0,
                0,
                EDGE_WIDTH*2,
                EDGE_WIDTH*2);
       
        //Note: bottom left corner is drawn after the outline... see below
       
        //outer outline
        graphics.setTransform(origTrans);
        graphics.setColor(Color.black);
        graphics.setStroke(ViewportGraphics.LINE_SOLID, 1);
        graphics.drawRect(0,
                0,
                mapPixelWidth-1,
                mapPixelHeight-1);
       
        //inner outline, extends to edges       
        graphics.drawLine(0, EDGE_WIDTH, mapPixelWidth, EDGE_WIDTH); //top
        graphics.drawLine(mapPixelWidth - EDGE_WIDTH, 0, mapPixelWidth - EDGE_WIDTH, mapPixelHeight); //right
        graphics.drawLine(0, mapPixelHeight - EDGE_WIDTH, mapPixelWidth, mapPixelHeight - EDGE_WIDTH); //bottom
        graphics.drawLine(EDGE_WIDTH, 0, EDGE_WIDTH, mapPixelHeight)//left


        //bottom left corner
        AffineTransform bottomleftTrans = graphics.getTransform();
        bottomleftTrans.translate(0, mapPixelHeight - EDGE_WIDTH*2);
        graphics.setTransform(bottomleftTrans);
        graphics.setColor(Color.white);
        graphics.fillRect(0,
                0,
                EDGE_WIDTH*2,
                EDGE_WIDTH*2);
        graphics.setColor(Color.black);
        graphics.drawOval(EDGE_WIDTH/4, EDGE_WIDTH/4, EDGE_WIDTH*2 - EDGE_WIDTH/2, EDGE_WIDTH*2 - EDGE_WIDTH/2);
        graphics.fillOval(EDGE_WIDTH - 1, EDGE_WIDTH - 1, 2, 2);
        graphics.drawRect(0,
                0,
                EDGE_WIDTH*2,
                EDGE_WIDTH*2);
        graphics.setTransform(origTrans);
       
        //-------------------------
        //draw labels
        //-------------------------
        graphics.setFont(font);
        graphics.setColor(Color.black);
       
        drawVerticalLabels(bounds, graphics, context, xCoords, yCoords, mapPixelWidth, mapPixelHeight);
        drawHorizontalLeftLabels(bounds, graphics, context, xCoords, yCoords, mapPixelWidth, mapPixelHeight);
        drawHorizontalRightLabels(bounds, graphics, context, xCoords, yCoords, mapPixelWidth, mapPixelHeight);
       
        /*
        //draw labels
        boolean showLabels =true;
        graphics.setFont(font);
        if (showLabels) {
            graphics.setColor(gridColor);
            for (int i = 1; i < yCoords.size() - 1; i++) {
                double y = yCoords.get(i).doubleValue();
                double x = xCoords.get(xCoords.size() - 1).doubleValue();
                Point pixel = context.worldToPixel(new Coordinate(x,y));
                //line is covered by white overlay
                if (pixel.y > mapPixelHeight - BOTTOM_STRIP_HEIGHT)
                    break;
                 graphics.drawString((int)(y)+"",
                                mapPixelWidth - RIGHT_STRIP_WIDTH + GRID_LINE_EXTENSION,
                                pixel.y,
                                ViewportGraphics.ALIGN_LEFT,
                                ViewportGraphics.ALIGN_MIDDLE);
            }
            for (int i = 1; i < xCoords.size() - 1; i++) {
                double x = xCoords.get(i).doubleValue();
                double y = yCoords.get(yCoords.size() - 1).doubleValue();
                Point pixel = context.worldToPixel(new Coordinate(x,y));
                //line is covered by white overlay
                if (pixel.x > mapPixelWidth - RIGHT_STRIP_WIDTH)
                    break;
                graphics.drawString((int)(x)+"",
                                pixel.x,
                                mapPixelHeight - BOTTOM_STRIP_HEIGHT + GRID_LINE_EXTENSION,
                                ViewportGraphics.ALIGN_MIDDLE,
                                ViewportGraphics.ALIGN_TOP);
            }
        } //showlabels
*/
    }

    private void drawVerticalLabels( Envelope bounds,
            ViewportGraphics graphics,
            MapGraphicContext context,
            List<Double> xCoords,
            List<Double> yCoords,
            int mapPixelWidth,
            int mapPixelHeight ) {
       
        int lineMiddles[] = {EDGE_WIDTH/2,
                mapPixelHeight-EDGE_WIDTH/2};
       
        for (int i = 0; i <lineMiddles.length; i++) {
            //left bound (shown on top)
            String label = formatBoundsText(bounds, bounds.getMinX());
            int textWidth = graphics.stringWidth(label);
            int textMinRightSide = LABEL_TEXT_BUFFER + EDGE_WIDTH*2 + textWidth;
            graphics.drawString(label,
                    LABEL_TEXT_BUFFER + EDGE_WIDTH*2,
                    lineMiddles[i],
                    ViewportGraphics.ALIGN_LEFT,
                    ViewportGraphics.ALIGN_MIDDLE);
   
            //right bound (shown on top)
            label = formatBoundsText(bounds, bounds.getMaxX());
            textWidth = graphics.stringWidth(label);
            int textMaxLeftSide = mapPixelWidth - LABEL_TEXT_BUFFER - EDGE_WIDTH*2 - textWidth;
            graphics.drawString(label,
                    mapPixelWidth - LABEL_TEXT_BUFFER - EDGE_WIDTH*2 - textWidth,
                    lineMiddles[i],
                    ViewportGraphics.ALIGN_LEFT,
                    ViewportGraphics.ALIGN_MIDDLE);
   
            //draw labels for the "in between" grid lines
            for (int j = 1; j < xCoords.size() - 1; j++) {
                label = formatBoundsText(bounds, xCoords.get(j));
                textWidth = graphics.stringWidth(label);
               
                double x = xCoords.get(j).doubleValue();
                double y = yCoords.get(0).doubleValue();
               
                if (i > 0) {
                    y = yCoords.get(yCoords.size()-1).doubleValue();
                }
                Point pixel = context.worldToPixel(new Coordinate(x,y));
               
                int gridLabelLeft = pixel.x - textWidth/2;
                int gridLabelRight = gridLabelLeft + textWidth;
               
                //label will collide with left/right edge label, so don't draw
                if (gridLabelLeft <= textMinRightSide || gridLabelRight >= textMaxLeftSide)
                    continue;
               
                graphics.drawString(label,
                                gridLabelLeft,
                                lineMiddles[i],
                                ViewportGraphics.ALIGN_LEFT,
                                ViewportGraphics.ALIGN_MIDDLE);
            }//for
           
        }//for
    }
   
    private void drawHorizontalLeftLabels( Envelope bounds,
            ViewportGraphics graphics,
            MapGraphicContext context,
            List<Double> xCoords,
            List<Double> yCoords,
            int mapPixelWidth,
            int mapPixelHeight ) {
       
        int lineMiddles[] = {mapPixelWidth-EDGE_WIDTH/2};
       
        AffineTransform origTrans = graphics.getTransform();
        AffineTransform tempTrans = (AffineTransform)origTrans.clone();
       
        graphics.setColor(Color.black);
       
        tempTrans.translate(EDGE_WIDTH, mapPixelHeight);
        tempTrans.rotate(-Math.PI/2); //rotate 90 degrees
        tempTrans.translate(0, -mapPixelHeight - (mapPixelWidth - mapPixelHeight));
        graphics.setTransform(tempTrans);
       
        for (int i = 0; i <lineMiddles.length; i++) {
            //top bound
            String label = formatBoundsText(bounds, bounds.getMinY());
            int textWidth = graphics.stringWidth(label);
            int textMaxLeftSide = LABEL_TEXT_BUFFER + EDGE_WIDTH*2 + textWidth;
            graphics.drawString(label,
                    LABEL_TEXT_BUFFER + EDGE_WIDTH*2,
                    lineMiddles[i],
                    ViewportGraphics.ALIGN_LEFT,
                    ViewportGraphics.ALIGN_MIDDLE);
   
            //bottom bound
            label = formatBoundsText(bounds, bounds.getMaxY());
            textWidth = graphics.stringWidth(label);
            int textMinRightSide = mapPixelHeight - LABEL_TEXT_BUFFER - EDGE_WIDTH*2 - textWidth;
            graphics.drawString(label,
                    mapPixelHeight - LABEL_TEXT_BUFFER - EDGE_WIDTH*2 - textWidth,
                    lineMiddles[i],
                    ViewportGraphics.ALIGN_LEFT,
                    ViewportGraphics.ALIGN_MIDDLE);
   
            //draw labels for the "in between" grid lines
            for (int j = 1; j < yCoords.size() - 1; j++) {
                label = formatBoundsText(bounds, yCoords.get(j));
                textWidth = graphics.stringWidth(label);
               
                double x = xCoords.get(0).doubleValue();
                double y = yCoords.get(j).doubleValue();
               
                if (i > 0) {
                    x = xCoords.get(xCoords.size()-1).doubleValue();
                }
                Point pixel = context.worldToPixel(new Coordinate(x,y));
               
                int gridLabelLeft =  mapPixelHeight - (pixel.y + textWidth/2);
                int gridLabelRight = gridLabelLeft + textWidth;
               
                //label will collide with left/right edge label, so don't draw
                if (gridLabelRight >= textMinRightSide || gridLabelLeft <= textMaxLeftSide)
                    continue;
               
                graphics.drawString(label,
                                gridLabelLeft,
                                lineMiddles[i],
                                ViewportGraphics.ALIGN_LEFT,
                                ViewportGraphics.ALIGN_MIDDLE);
            }//for
           
        }//for
       
        graphics.setTransform(origTrans);
    }


    private void drawHorizontalRightLabels( Envelope bounds,
            ViewportGraphics graphics,
            MapGraphicContext context,
            List<Double> xCoords,
            List<Double> yCoords,
            int mapPixelWidth,
            int mapPixelHeight ) {
       
        int lineMiddles[] = {EDGE_WIDTH/2};
       
        AffineTransform origTrans = graphics.getTransform();
        AffineTransform tempTrans = (AffineTransform)origTrans.clone();
       
       
        graphics.setColor(Color.BLACK);
        tempTrans.rotate(Math.PI/2); //rotate 90 degrees
        tempTrans.translate(0, -mapPixelHeight - (mapPixelWidth - mapPixelHeight));
        graphics.setTransform(tempTrans);
       
        for (int i = 0; i <lineMiddles.length; i++) {
            //top bound
            String label = formatBoundsText(bounds, bounds.getMaxY());
            int textWidth = graphics.stringWidth(label);
            int textMaxLeftSide = LABEL_TEXT_BUFFER + EDGE_WIDTH*2 + textWidth;
            graphics.drawString(label,
                    LABEL_TEXT_BUFFER + EDGE_WIDTH*2,
                    lineMiddles[i],
                    ViewportGraphics.ALIGN_LEFT,
                    ViewportGraphics.ALIGN_MIDDLE);
   
            //bottom bound
            label = formatBoundsText(bounds, bounds.getMinY());
            textWidth = graphics.stringWidth(label);
            int textMinRightSide = mapPixelHeight - LABEL_TEXT_BUFFER - EDGE_WIDTH*2 - textWidth;
            graphics.drawString(label,
                    mapPixelHeight - LABEL_TEXT_BUFFER - EDGE_WIDTH*2 - textWidth,
                    lineMiddles[i],
                    ViewportGraphics.ALIGN_LEFT,
                    ViewportGraphics.ALIGN_MIDDLE);
   
            //draw labels for the "in between" grid lines
            for (int j = 1; j < yCoords.size() - 1; j++) {
                label = formatBoundsText(bounds, yCoords.get(j));
                textWidth = graphics.stringWidth(label);
               
                double x = xCoords.get(0).doubleValue();
                double y = yCoords.get(j).doubleValue();
               
                if (i > 0) {
                    x = xCoords.get(xCoords.size()-1).doubleValue();
                }
                Point pixel = context.worldToPixel(new Coordinate(x,y));
               
                int gridLabelLeft =  (pixel.y - textWidth/2);
                int gridLabelRight = gridLabelLeft + textWidth;
               
                //label will collide with left/right edge label, so don't draw
                if (gridLabelRight >= textMinRightSide || gridLabelLeft <= textMaxLeftSide)
                    continue;
               
                graphics.drawString(label,
                                gridLabelLeft,
                                lineMiddles[i],
                                ViewportGraphics.ALIGN_LEFT,
                                ViewportGraphics.ALIGN_MIDDLE);
            }//for
           
        }//for
       
        graphics.setTransform(origTrans);
    }

   
    /**
     * formats an arbitrary x or y spatial position for display purposes.
     *
     * @param d
     * @return
     */
    private String formatBoundsText(Envelope bounds, double d) {
        if (bounds.getWidth() > 100) {
            return Math.round(d)+"";
        }
        if (d == 0) {
            return "0.0";
        }
        DecimalFormat df = new DecimalFormat("#.0");
        return df.format(d);
    }
   
    /*
     * returns a two element array, where each element is list.
     * the first list represents x-coordinates of vertical grid lines, and
     * the second list represents y coordinates of horizontal grid lines.
     */
    private List<Double>[] chooseGridLines(Envelope bounds) {
        double[] gridSizeChoices = { 1, 2, 5, 10, 25, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000 };
        int preferredNumberOfGridLines = 2; //approximately, but +/- a couple is okay
       
        double xSizeGuess = (bounds.getMaxX() - bounds.getMinX()) / preferredNumberOfGridLines;
        double xSize = findClosest(gridSizeChoices, xSizeGuess);
       
        double ySizeGuess = (bounds.getMaxY() - bounds.getMinY()) / preferredNumberOfGridLines;
        double ySize = findClosest(gridSizeChoices, ySizeGuess);
       
        double max = Math.max(xSize, ySize);
        xSize = max;
        ySize = max;
       
        // make list of all the x-coordinates (vertical grid lines)
        double firstX = Math.round(bounds.getMinX() / xSize) * xSize;
        if (firstX > bounds.getMinX()){
            firstX -= xSize;
        }
        List xList = new ArrayList();
        double xCoord = firstX;
        while (xCoord < bounds.getMaxX() + xSize) {
            xList.add(xCoord);
            xCoord += xSize;
        }
       
        // make list of all the y-coordinates (horizontal grid lines)
        double firstY = Math.round(bounds.getMaxY() / ySize) * ySize;
        if (firstY < bounds.getMaxY()){
            firstY += ySize;
        }
        List yList = new ArrayList();
        double yCoord = firstY;
        while (yCoord > bounds.getMinY() - ySize) {
            yList.add(yCoord);
            yCoord -= ySize;
        }
       
        List[] result = {xList, yList};
        return result;
       
    }
   
    private double findClosest(double[] choices, double val) {
        if (val < choices[0])
            return choices[0];
        for (int i = 0; i < choices.length -1; i++) {
            if (val > choices[i] && val < choices[i+1])
                return choices[i];
        }
        return choices[choices.length - 1];
    }

    /**
     * Draws grid similarly to the "world" version, but with some changes:
     *  - Center the grid on the screen
     *  - label the grid lines in CRS units
     *  - outline the grid
     *
     * @param context
     * @param showLabels is true, the bottom and right edges of the map are covered with
     * white strips, and labels for the grid lines are placed in the white strips.
     */
  private void drawGrid( MapGraphicContext context, boolean showLabels ) {
       
        GridStyle style = getStyle(context.getLayer());
        double[] gridSize=style.getGridSize();
    

        try{
            MathTransform mt = CRS.findMathTransform(DefaultGeographicCRS.WGS84, context.getCRS(), true);
       
            if( !mt.isIdentity() ){
                double x=gridSize[0]/2.0;
                double y=gridSize[1]/2.0;
                double[] toTransform=new double[]{-x,-y,x,y};
                double[] dest=new double[4];
                mt.transform(toTransform,0,dest,0,2);
                gridSize=new double[]{Math.abs(dest[2]-dest[0]), Math.abs(dest[3]-dest[1])};
            }
        }catch (Exception e) {
            MapGraphicPlugin.log("",e); //$NON-NLS-1$
        }

        Envelope bounds = context.getViewportModel().getBounds();
       
        Coordinate centerCoord = bounds.centre();
        gridSize = style.getGridSize();
        Coordinate topLeftCenterCoord = new Coordinate(centerCoord.x - gridSize[0]/2,
                                                       centerCoord.y + gridSize[1]/2);
        Coordinate topLeftMostCoord = new Coordinate(topLeftCenterCoord);
        while (topLeftMostCoord.x - gridSize[0] > bounds.getMinX()) {
            topLeftMostCoord.x -= gridSize[0];
        }
        while (topLeftMostCoord.y + gridSize[1] < bounds.getMaxY()) {
            topLeftMostCoord.y += gridSize[1];
        }
        Coordinate coord = topLeftMostCoord;

        ViewportGraphics graphics = context.getGraphics();
        int mapPixelWidth = context.getMapDisplay().getWidth();
        int mapPixelHeight = context.getMapDisplay().getHeight();
       
        //cover the right side and bottom of map with thin strips
        final int RIGHT_STRIP_WIDTH = (int)(mapPixelWidth * 0.05);
        final int BOTTOM_STRIP_HEIGHT = (int)(mapPixelHeight * 0.03);
        final int GRID_LINE_EXTENSION = (int)(RIGHT_STRIP_WIDTH * 0.1);
        graphics.setColor(Color.white);
        graphics.fillRect(mapPixelWidth - RIGHT_STRIP_WIDTH,
                          0,
                          RIGHT_STRIP_WIDTH,
                          mapPixelHeight);
        graphics.fillRect(0,
                          mapPixelHeight - BOTTOM_STRIP_HEIGHT,
                          mapPixelWidth,
                          BOTTOM_STRIP_HEIGHT);  
       
        //draw grid lines
        graphics.setColor(style.getColor());
        Point pixel = null;
        while(true){
            pixel = context.worldToPixel(coord);           
            coord.x+=gridSize[0];
            coord.y-=gridSize[1];
            Point next=context.worldToPixel(coord);
            if( next.x-pixel.x<2 || next.y-pixel.y<2 ){
                context.getLayer().setStatus(ILayer.WARNING);
                context.getLayer().setStatusMessage(Messages.GridMapGraphic_grids_too_close);
                break;
            }
            if( (pixel.x>=mapPixelWidth && pixel.y>=mapPixelHeight) )
                break;
           
            //draw vertical lines and labels
            if( pixel.x<mapPixelWidth)
                graphics.drawLine(pixel.x,
                                  0,
                                  pixel.x,
                                  mapPixelHeight - BOTTOM_STRIP_HEIGHT + GRID_LINE_EXTENSION);
                if (showLabels) {
                    graphics.drawString((int)(coord.y)+"",
                                    pixel.x,
                                    mapPixelHeight - BOTTOM_STRIP_HEIGHT + GRID_LINE_EXTENSION,
                                    ViewportGraphics.ALIGN_MIDDLE,
                                    ViewportGraphics.ALIGN_TOP);
                }
           
            //draw horizontal lines and labels
            if( pixel.y<mapPixelHeight)
                graphics.drawLine(0,
                                  pixel.y,
                                  mapPixelWidth - RIGHT_STRIP_WIDTH + GRID_LINE_EXTENSION,
                                  pixel.y);
                if (showLabels) {
                    graphics.drawString((int)(coord.x)+"",
                                    mapPixelWidth - RIGHT_STRIP_WIDTH + GRID_LINE_EXTENSION,
                                    pixel.y,
                                    ViewportGraphics.ALIGN_LEFT,
                                    ViewportGraphics.ALIGN_MIDDLE);
                }
            pixel=next;
        }
   
        //outline the map       
        graphics.drawRect(0,
                          0,
                          mapPixelWidth - RIGHT_STRIP_WIDTH,
                          mapPixelHeight - BOTTOM_STRIP_HEIGHT);
     
    }       
   
    private GridStyle getStyle( ILayer layer ) {
        GridStyle gridStyle = (GridStyle) layer.getStyleBlackboard().get(GridStyle.ID);
        if( gridStyle==null ){
            return GridStyle.DEFAULT_STYLE;
        }
        return gridStyle;
    }

    /**
     * calculates the closest point to x,y. 
     *
     * @param x x coord in screen coords
     * @param y y coord in screen coords
     * @param layer layer containing this map graphic
     * @return the closest point on the grid  in map coords 
     * @throws FactoryException
     */
    public double[] closest( int x, int y, ILayer layer ) throws FactoryException {
        switch( getStyle(layer).getType() ) {
        case SCREEN:
           
            return screenClosest(x,y,layer);
        case WORLD:
            return worldClosest(x, y,layer);
        default:
            AssertionError e=new AssertionError("Should be impossible to reach here: "+getStyle(layer).getType());
            MapGraphicPlugin.log(null, e );
            throw e;
        }
    }

    private double[] screenClosest( int x, int y, ILayer layer ) {
        double[] gridSize = getStyle(layer).getGridSize();

        double newx = Math.round(x/gridSize[0])*gridSize[0];
        double newy = Math.round(y/gridSize[1])*gridSize[1];
       
        Coordinate result = layer.getMap().getViewportModel().pixelToWorld((int)newx, (int)newy);
        return new double[]{result.x, result.y};
    }

    private double[] worldClosest( int x1, int y1, ILayer layer ) throws FactoryException {
        Coordinate coord = layer.getMap().getViewportModel().pixelToWorld(x1, y1);
        CoordinateReferenceSystem crs = layer.getMap().getViewportModel().getCRS();
        MathTransform mt = CRS.findMathTransform(DefaultGeographicCRS.WGS84, crs);

        double[] gridSize = getStyle(layer).getGridSize();
        try{
       
            if( !mt.isIdentity() ){
                double tx=gridSize[0]/2.0;
                double ty=gridSize[1]/2.0;
                double[] toTransform=new double[]{-tx,-ty,tx,ty};
                double[] dest=new double[4];
                mt.transform(toTransform,0,dest,0,2);
                gridSize=new double[]{Math.abs(dest[2]-dest[0]), Math.abs(dest[3]-dest[1])};
            }
        }catch (Exception e) {
            MapGraphicPlugin.log("",e); //$NON-NLS-1$
        }
        double newx = Math.round(coord.x/gridSize[0])*gridSize[0];
        double newy = Math.round(coord.y/gridSize[1])*gridSize[1];
        return new double[]{newx,newy};
    }


}
TOP

Related Classes of org.locationtech.udig.printing.ui.pdf.AntiqueGridMapGraphic

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.