|
From: jv <cib...@gm...> - 2009-09-21 11:32:35
|
Hi! This is the code I've been working for some time in order to
create an UTM map with a series of areas marked with a circle, a cross
or a square. Without the fantastic help provided by Jody and Michael I
would be unable to achieve it, so many thanks dudes!
Next phase will include adding actual marks on the map in order to
show point-size features.
============================================================================
package edu.ub.bio.wms.model;
public enum Fiability {
UNKNOWN, UNSURE, SURE, DISAPPEARED;
}
============================================================================
package edu.ub.bio.wms.mapa;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;
import edu.ub.bio.framework.SystemException;
import edu.ub.bio.wms.model.Fiability;
import java.awt.Color;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.geotools.data.memory.MemoryDataStore;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.map.DefaultMapLayer;
import org.geotools.map.MapLayer;
import org.geotools.styling.Fill;
import org.geotools.styling.PolygonSymbolizer;
import org.geotools.styling.Style;
import org.geotools.styling.StyleBuilder;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
/**
*
* @author ciberado
*/
public class UTMMapLayerBuilder {
private MemoryDataStore dataStore;
private CoordinateReferenceSystem crs;
private Map<Fiability, SimpleFeatureType> featureTypes =
new HashMap<Fiability, SimpleFeatureType>();
public UTMMapLayerBuilder(CoordinateReferenceSystem crs) {
this.dataStore = new MemoryDataStore();
this.crs = crs;
for (Fiability fiab : Fiability.values()) {
featureTypes.put(fiab, createSpeciesFeatureType(fiab));
}
}
public void addRegion(String id, String name, double x, double y,
double size, Fiability fiability) {
Geometry polygon = null;
switch (fiability) {
case DISAPPEARED : polygon = createCrossPolygon(x, y, size); break;
case UNSURE : polygon = createCirclePolygon(x, y, size); break;
default : polygon = createSquarePolygon(x, y, size); break;
}
SimpleFeature feature = SimpleFeatureBuilder.build(
featureTypes.get(fiability),
new Object[]{polygon, name}, id);
dataStore.addFeature(feature);
}
public MapLayer buildLayer(Color color) {
try {
DefaultMapLayer layer = null;
for (String currentName : dataStore.getTypeNames()) {
StyleBuilder builder = new StyleBuilder();
PolygonSymbolizer symbolizer = builder.createPolygonSymbolizer(color);
Fiability fiability = Fiability.valueOf(currentName);
Fill fill = createFillByFiability(builder, color, fiability);
symbolizer.setFill(fill);
Style style = builder.createStyle(symbolizer);
FeatureCollection featureCollection =
dataStore.getFeatureSource(currentName).getFeatures();
layer = new DefaultMapLayer(featureCollection, style);
layer.setTitle("SpeciesList");
}
return layer;
} catch (IOException e) {
throw new SystemException(e);
}
}
private Fill createFillByFiability(StyleBuilder builder, Color
color, Fiability fiability) {
Fill fill;
switch (fiability) {
case DISAPPEARED : fill = builder.createFill(Color.BLACK, 0.33); break;
case SURE : fill = builder.createFill(Color.GREEN, 0.33); break;
case UNSURE : fill = builder.createFill(Color.ORANGE, 0.33); break;
case UNKNOWN : fill = builder.createFill(Color.BLUE, 0.33); break;
default: fill = null;
}
return fill;
}
private SimpleFeatureType createSpeciesFeatureType(Fiability fiability) {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName(fiability.name());
builder.setNamespaceURI("http://biodiver.bio.ub.es/geo");
builder.setCRS(crs);
builder.add("squareGeometry", Polygon.class);
builder.add("speciesName", String.class);
SimpleFeatureType featureType = builder.buildFeatureType();
return featureType;
}
private static Geometry createSquarePolygon(double x, double y, double size) {
GeometryFactory gf = JTSFactoryFinder.getGeometryFactory(null);
Coordinate[] polygonCoordinates = new Coordinate[5];
polygonCoordinates[0] = new Coordinate(x, y);
polygonCoordinates[1] = new Coordinate(x + size, y);
polygonCoordinates[2] = new Coordinate(x + size, y + size);
polygonCoordinates[3] = new Coordinate(x, y + size);
polygonCoordinates[4] = polygonCoordinates[0];
LinearRing ring = gf.createLinearRing(polygonCoordinates);
Polygon polygon = gf.createPolygon(ring, null);
return polygon;
}
private static Geometry createCirclePolygon(double x, double y,
final double size) {
final int SIDES = 48;
double radio = size / 2;
x = x + radio / 2;
y = y + radio / 2;
GeometryFactory factory = JTSFactoryFinder.getGeometryFactory(null);
Coordinate coords[] = new Coordinate[SIDES+1];
for( int i = 0; i < SIDES; i++){
double angle = ((double) i / (double) SIDES) * Math.PI * 2.0;
double dx = Math.cos( angle ) * radio;
double dy = Math.sin( angle ) * radio;
coords[i] = new Coordinate( (double) x + dx, (double) y + dy );
}
coords[SIDES] = coords[0];
LinearRing ring = factory.createLinearRing( coords );
Polygon polygon = factory.createPolygon( ring, null );
return polygon;
}
private static Geometry createCrossPolygon(double x, double y, double size) {
GeometryFactory gf = JTSFactoryFinder.getGeometryFactory(null);
double s = size / 3 *1.05;
double ss = size /2;
double sss = size * 0.95;
double[] xy = {
s,0,
s,s,
0,s,
0,ss,
s,ss,
s,sss,
ss,sss,
ss,ss,
sss,ss,
sss,s,
ss,s,
ss,0,
s,0
};
Coordinate[] polygonCoordinates = new Coordinate[xy.length / 2];
for (int idx=0; idx < polygonCoordinates.length; idx++) {
polygonCoordinates[idx] = new Coordinate(x+xy[idx*2], y+xy[idx*2+1]);
}
LinearRing ring = gf.createLinearRing(polygonCoordinates);
Polygon polygon = gf.createPolygon(ring, null);
return polygon;
}
}
============================================================================
Little example about how to use it:
double minx = 0;
double miny = 0;
double maxx = 50;
double maxy = 50;
crs = CRS.decode("EPSG:32631");
UTMMapLayerBuilder layerBuilder = new UTMMapLayerBuilder(crs);
layerBuilder.addRegion("point_" + idx, 5, 5, 10, Fiability.UNSURE);
layerBuilder.addRegion("point_" + idx, 25, 35, 10, Fiability.SURE);
layerBuilder.addRegion("point_" + idx, 5, 25, 10, Fiability.DISAPPEARED);
BufferedImage image =
new BufferedImage(getImageWidth(), getImageHeight(),
BufferedImage.TYPE_INT_ARGB);
HashMap hints = new HashMap();
hints.put("optimizedDataLoadingEnabled", Boolean.TRUE);
hints.put(RenderingHints.VALUE_RENDER_QUALITY, Boolean.TRUE);
hints.put(RenderingHints.VALUE_ANTIALIAS_ON, Boolean.TRUE);
GTRenderer renderer = new StreamingRenderer();
renderer.setRendererHints(hints);
MapLayer mapLayer = layerBuilder.buildLayer(styleToColor(getStyle()));
if (mapLayer != null) {
MapContext mapContext = new GraphicEnhancedMapContext(
new MapLayer[] {mapLayer}, crs);
renderer.setContext(mapContext);
Coordinate c1 = new Coordinate(minx, miny);
Coordinate c2 = new Coordinate(maxx, maxy);
Envelope activeArea = new Envelope(c1, c2);
mapContext.setAreaOfInterest(activeArea, crs);
Graphics2D g = image.createGraphics();
renderer.paint(g, new Rectangle(getImageWidth(), getImageHeight()),
activeArea);
}
|