Re: Resampling from lat/lon to projection

Kjell-

Kjell Roang wrote:

I fully agree. I would try to use VisAd as much as possible, and the
conversation with you has given me hints how to use another projection
package inside VisAd. I must then find a way to put GRIB data into VisAd and
get images and data out of VisAd.

I've attached a copy of a version of ProjectionCoordinateSystem
from our IDV package that shows how we adapt our Projection
class (ucar.unidata.geoloc.Projection) to a VisADCoordinateSystem.
This is an older version (we've made mods for other reasons that
are not applicable here), but should give you a guide for
how to convert a GeoTools Projection to a VisADCoordinateSystem.

Don
*************************************************************
Don Murray                               UCAR Unidata Program
dmurray@xxxxxxxxxxxxxxxx                        P.O. Box 3000
(303) 497-8628                              Boulder, CO 80307
http://www.unidata.ucar.edu/staff/donm
*************************************************************

// $Id: ProjectionCoordinateSystem.java,v 1.5 2001/11/06 17:18:44 dmurray Exp $
/*
 * Copyright 1997-2000 Unidata Program Center/University Corporation for
 * Atmospheric Research, P.O. Box 3000, Boulder, CO 80307,
 * support@xxxxxxxxxxxxxxxxx
 * 
 * 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; either version 2.1 of the License, or (at
 * your option) any later version.
 * 
 * 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 ucar.visad;

import ucar.unidata.geoloc.*;
import visad.*;
import visad.georef.MapProjection;

/** 
 * Adapts a ucar.unidata.Projection into a VisAD MapProjection CoordinateSystem.
 * Transforms between world coordinates (x,y) in km and lat/lon in degrees.
 * Reference is lat/lon (RealTupleType.LatitudeLongitudeTuple)
 *
 * @see ucar.unidata.geoloc.Projection
 * @see visad.georef.MapProjection
 * @author Stuart Wier
 * @author Don Murray
 * @version $Revision: 1.5 $ $Date: 2001/11/06 17:18:44 $
 */
public class ProjectionCoordinateSystem extends MapProjection {

        private Projection projection;
        private ProjectionPointImpl workP = new ProjectionPointImpl();
        private LatLonPointImpl workL = new LatLonPointImpl();

    /**
     * Constructs an instance from the supplied Projection. The 
     * reference coordinate system is RealTupleType.LatitudeLongitudeTuple;
     * the incoming units are assumed to be km (1000 m).
     */
    public ProjectionCoordinateSystem (Projection projection) 
        throws VisADException
    {
        super(RealTupleType.LatitudeLongitudeTuple, 
              new Unit[] {CommonUnit.meter.scale(1000.0), 
                          CommonUnit.meter.scale(1000.0)});
        
        this.projection = projection;
    }
    
    /**
     * Get a reasonable bounding box in this coordinate system. MapProjections 
     * are typically specific to an area of the world; there's no bounding 
     * box that works for all projections so each subclass must implement
     * this method. 
     *
     * @return the default MapArea of the Projection
     */
    public java.awt.geom.Rectangle2D getDefaultMapArea()
    {
        return projection.getDefaultMapArea();
    }

    /**
     * Get the Projection used for the transformations.
     * @return projection
     */
    public Projection getProjection() {
        return projection;
    }

    /**
     * Convert world coordinates to lat/lon.  Input coords are in km.
     * @param  world   world projection coordinates (x = world[0][i])
     * @return corresponding lat/lon values (lat = latlon[0][i])
     * @throws VisADException  world coordinate array length != 2
     */
    public double[][] toReference(double[][] world) 
        throws VisADException
    {
        if ( world == null || world.length != 2)
            throw new VisADException(
              "ProjectionCoordinateSystem.toReference: " +
                  "null world array or wrong dimension ");

        double[][] latlon = new double[2][world[0].length];
        
        LatLonPoint llPoint;
        for (int i = 0; i < latlon[0].length; i++)
            {
                workP.setLocation(world[0][i], world[1][i]); 
                llPoint = projection.projToLatLon(workP);
                latlon[getLatitudeIndex()][i] = llPoint.getLatitude();
                latlon[getLongitudeIndex()][i] = llPoint.getLongitude();
            }
        return latlon;
    }
    
    /**
     * Convert lat/lon coordinates to world (projection) coords.  
     * @param   lat/lon values (lat = latlon[0][i])
     * @return  world projection coordinates (x = world[0][i])
     * @throws  VisADException  latlon coordinate array length != 2
     */
    public double[][] fromReference(double[][] latlon) 
        throws VisADException
    {
        if ( latlon == null || latlon.length != 2)
            throw new VisADException(
              "ProjectionCoordinateSystem.toReference: " +
                  "null latlon array or wrong dimension ");
        double[][] world = new double[2][latlon[0].length];
        ProjectionPoint projPoint;
        for (int i = 0; i < latlon[0].length; i++)
            {
                workL.setLatitude(latlon[getLatitudeIndex()][i]);
                workL.setLongitude(latlon[getLongitudeIndex()][i]);
                projPoint = projection.latLonToProj(workL);
                world[0][i] = projPoint.getX();
                world[1][i] = projPoint.getY();
            }
        return world;
    }
    
    /** 
     * Check for equality of CoordinateSystem objects 
     * @param  obj  other object in question
     * @return  true if the object in question is a ProjectionCoordinateSystem
     *          and it's Projection is equal the this object's Projection
     */
    public boolean equals (Object obj) 
    {
        if (!(obj instanceof ProjectionCoordinateSystem))
            return false;
        ProjectionCoordinateSystem that = (ProjectionCoordinateSystem) obj;
        return that.projection.equals(projection);
    }
    
} // end ProjectionCoordinateSystem class