//$HeadURL$
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2008 by:
Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
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
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.igeo.views.swing.map;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.Iterator;
import java.util.List;
import org.deegree.framework.log.ILogger;
import org.deegree.framework.log.LoggerFactory;
import org.deegree.graphics.displayelements.DisplayElement;
import org.deegree.graphics.displayelements.DisplayElementFactory;
import org.deegree.graphics.sld.LineSymbolizer;
import org.deegree.graphics.sld.PolygonSymbolizer;
import org.deegree.graphics.sld.StyleFactory;
import org.deegree.graphics.sld.UserStyle;
import org.deegree.graphics.transformation.GeoTransform;
import org.deegree.igeo.mapmodel.MapModel;
import org.deegree.model.feature.Feature;
import org.deegree.model.feature.FeatureCollection;
import org.deegree.model.feature.FeatureProperty;
import org.deegree.model.spatialschema.Curve;
import org.deegree.model.spatialschema.MultiCurve;
import org.deegree.model.spatialschema.MultiPoint;
import org.deegree.model.spatialschema.MultiSurface;
import org.deegree.model.spatialschema.Position;
import org.deegree.model.spatialschema.Ring;
import org.deegree.model.spatialschema.Surface;
/**
* The <code></code> class TODO add class documentation here.
*
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
*
* @author last edited by: $Author$
*
* @version $Revision$, $Date$
*
*/
public class HighlightRenderer {
private static final ILogger LOG = LoggerFactory.getLogger( HighlightRenderer.class );
private List<FeatureCollection> selectedFeatures;
private MapModel mapModel;
private DefaultMapComponent owner;
private static Color pointFillColor = Color.RED;
private static Color pointStrokeColor = Color.BLACK;
private static int pointSize = 7;
private static LineSymbolizer lineSymbolizer;
private static PolygonSymbolizer polygonSymbolizer;
static {
UserStyle style = (UserStyle) StyleFactory.createLineStyle( Color.decode( "0xFF8800" ), 3, 1, 0,
Double.MAX_VALUE );
lineSymbolizer = (LineSymbolizer) style.getFeatureTypeStyles()[0].getRules()[0].getSymbolizers()[0];
style = (UserStyle) StyleFactory.createPolygonStyle( Color.WHITE, 0.5f, Color.decode( "0xFF8800" ), 3, 1, 0,
Double.MAX_VALUE );
polygonSymbolizer = (PolygonSymbolizer) style.getFeatureTypeStyles()[0].getRules()[0].getSymbolizers()[0];
}
/**
*
* @param mapModel
* @param owner
*/
HighlightRenderer( MapModel mapModel, DefaultMapComponent owner ) {
this.owner = owner;
this.mapModel = mapModel;
}
void highlightFeatures( Graphics g ) {
if ( selectedFeatures != null ) {
GeoTransform gt = mapModel.getToTargetDeviceTransformation();
for ( FeatureCollection fc : selectedFeatures ) {
Iterator<Feature> iter = fc.iterator();
while ( iter.hasNext() ) {
Feature feature = iter.next();
renderFeature( g, gt, feature );
}
}
}
}
private void renderFeature( Graphics g, GeoTransform gt, Feature feature ) {
FeatureProperty[] fp = feature.getProperties();
for ( FeatureProperty property : fp ) {
Object value = property.getValue();
if ( value instanceof Feature ) {
// recursive invokation for complex features/properties
renderFeature( g, gt, (Feature) value );
} else if ( value instanceof FeatureCollection ) {
// recursive invokation for complex features/properties
Iterator<Feature> iter = ( (FeatureCollection) value ).iterator();
while ( iter.hasNext() ) {
renderFeature( g, gt, iter.next() );
}
} else if ( value instanceof org.deegree.model.spatialschema.Point ) {
org.deegree.model.spatialschema.Point point = (org.deegree.model.spatialschema.Point) value;
drawPoint( g, pointFillColor, gt, point.getX(), point.getY() );
} else if ( value instanceof MultiPoint ) {
MultiPoint mp = (MultiPoint) value;
org.deegree.model.spatialschema.Point[] points = mp.getAllPoints();
for ( org.deegree.model.spatialschema.Point point : points ) {
drawPoint( g, pointFillColor, gt, point.getX(), point.getY() );
}
} else if ( value instanceof Curve ) {
Curve curve = (Curve) value;
drawLine( g, gt, feature, curve );
} else if ( value instanceof MultiCurve ) {
MultiCurve multiCurve = (MultiCurve) value;
Curve[] curves = multiCurve.getAllCurves();
for ( Curve curve : curves ) {
drawLine( g, gt, feature, curve );
}
} else if ( value instanceof Surface ) {
Surface surface = (Surface) value;
drawPolygon( g, gt, feature, surface );
} else if ( value instanceof MultiSurface ) {
MultiSurface multiSurface = (MultiSurface) value;
Surface[] surfaces = multiSurface.getAllSurfaces();
for ( Surface surface : surfaces ) {
drawPolygon( g, gt, feature, surface );
}
}
}
}
/**
* draws a Surface onto the passed graphic context using the {@link PolygonSymbolizer} that has been created in the
* classes static block
*
* @param g
* @param gt
* @param feature
* @param surface
*/
private void drawPolygon( Graphics g, GeoTransform gt, Feature feature, Surface surface ) {
try {
DisplayElement de = DisplayElementFactory.buildPolygonDisplayElement( feature, surface, polygonSymbolizer );
de.paint( g, gt, 1 );
} catch ( Exception e ) {
LOG.logError( e.getMessage(), e );
}
Position[] pos = surface.getSurfaceBoundary().getExteriorRing().getPositions();
double dr = ( 255d - pointFillColor.getRed() ) / pos.length;
double dg = ( 255d - pointFillColor.getGreen() ) / pos.length;
double db = ( 255d - pointFillColor.getBlue() ) / pos.length;
double rr = 255;
double gg = 255;
double bb = 255;
for ( Position position : pos ) {
Color color = new Color( (int) Math.round( rr ), (int) Math.round( gg ), (int) Math.round( bb ) );
rr -= dr;
gg -= dg;
bb -= db;
drawPoint( g, color, gt, position.getX(), position.getY() );
}
Ring[] innerRings = surface.getSurfaceBoundary().getInteriorRings();
for ( Ring ring : innerRings ) {
pos = ring.getPositions();
for ( Position position : pos ) {
drawPoint( g, pointFillColor, gt, position.getX(), position.getY() );
}
}
}
/**
* draws a Curce onto the passed graphic context using the {@link LineSymbolizer} that has been created in the
* classes static block
*
* @param g
* @param gt
* @param feature
* @param curve
*/
private void drawLine( Graphics g, GeoTransform gt, Feature feature, Curve curve ) {
try {
DisplayElement de = DisplayElementFactory.buildLineStringDisplayElement( feature, curve, lineSymbolizer );
de.paint( g, gt, 1 );
} catch ( Exception e ) {
LOG.logError( e.getMessage(), e );
}
try {
Position[] pos = curve.getAsLineString().getPositions();
double dr = ( 255d - pointFillColor.getRed() ) / pos.length;
double dg = ( 255d - pointFillColor.getGreen() ) / pos.length;
double db = ( 255d - pointFillColor.getBlue() ) / pos.length;
double rr = 255;
double gg = 255;
double bb = 255;
for ( Position position : pos ) {
Color color = new Color( (int) Math.round( rr ), (int) Math.round( gg ), (int) Math.round( bb ) );
rr -= dr;
gg -= dg;
bb -= db;
drawPoint( g, color, gt, position.getX(), position.getY() );
}
} catch ( Exception e ) {
LOG.logError( e.getMessage(), e );
}
}
/**
* draws a Point onto the passed graphic context using style read from deegree iGeoDesktop configuration
*
* @param g
* @param gt
* @param px
* @param py
*/
private void drawPoint( Graphics g, Color color, GeoTransform gt, double px, double py ) {
double x = gt.getDestX( px );
double y = gt.getDestY( py );
Graphics2D g2 = (Graphics2D) g;
g2.setStroke( new BasicStroke( 1 ) );
g2.setColor( color );
int size2 = pointSize / 2;
g2.fillRect( (int) x - size2, (int) y - size2, pointSize, pointSize );
g2.setColor( pointStrokeColor );
g2.drawRect( (int) x - size2, (int) y - size2, pointSize, pointSize );
}
/**
* adjust the point to the size of the panel, so that the resulting point lays inside of the zoom panel
*
* @param point
* the point to adjust
* @return the adjusted point inside the zoom panel
*/
protected Point adjustPointToPanelSize( Point point ) {
int x = Double.valueOf( point.getX() ).intValue();
int y = Double.valueOf( point.getY() ).intValue();
if ( x < 0 ) {
x = 0;
} else if ( x > owner.getWidth() - 1 ) {
x = owner.getWidth() - 1;
}
if ( y < 0 ) {
y = 0;
} else if ( y > owner.getHeight() - 1 ) {
y = owner.getHeight() - 1;
}
return new Point( x, y );
}
/**
*
* @param selectedFeatures
*/
void setSelectedFeatures( List<FeatureCollection> selectedFeatures ) {
this.selectedFeatures = selectedFeatures;
}
}