package org.vfny.geoserver.wms.responses.map.htmlimagemap;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Logger;
import junit.framework.TestCase;
import org.geoserver.platform.GeoServerResourceLoader;
import org.geoserver.wms.WMSExtensions;
import org.geotools.data.DataSourceException;
import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureSource;
import org.geotools.data.property.PropertyDataStore;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.SchemaException;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.test.*;
import org.geotools.styling.SLDParser;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.NoSuchAuthorityCodeException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.vfny.geoserver.global.GeoserverDataDirectory;
import org.vfny.geoserver.wms.GetMapProducer;
import org.vfny.geoserver.wms.WMSMapContext;
import com.vividsolutions.jts.geom.Envelope;
/**
* Test suite for HTMLImageMapMapProducer GetMapProducer
*
* @author Mauro Bartolomeoli
*/
public class HTMLImageMapTest extends TestCase {
private static final StyleFactory sFac = CommonFactoryFinder.getStyleFactory(null);
private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger(HTMLImageMapTest.class.getPackage().getName());
//GetMapProducerFactorySpi mapFactory=null;
GetMapProducer mapProducer=null;
CoordinateReferenceSystem WGS84=null;
DataStore testDS = null;
int mapWidth=600;
int mapHeight=600;
public void setUp() throws Exception {
// initializes GeoServer Resource Loading (is needed by some tests to not produce exceptions)
System.setProperty("org.geotools.referencing.forceXY", "true");
File testdata=TestData.file(this, ".");
System.setProperty("GEOSERVER_DATA_DIR", testdata.getAbsolutePath());
GeoServerResourceLoader loader = new GeoServerResourceLoader(testdata);
GenericWebApplicationContext context = new GenericWebApplicationContext();
context.getBeanFactory().registerSingleton("resourceLoader", loader);
GeoserverDataDirectory.init(context);
// initialized WGS84 CRS (used by many tests)
WGS84=CRS.decode("EPSG:4326");
testDS=getTestDataStore();
// initializes GetMapProducer factory and actual producer
//this.mapFactory = getProducerFactory();
this.mapProducer=getProducerInstance();
super.setUp();
}
public void tearDown() throws Exception {
//this.mapFactory = null;
this.mapProducer=null;
super.tearDown();
}
/*protected GetMapProducerFactorySpi getProducerFactory() {
return new HTMLImageMapMapProducerFactory();
}*/
protected GetMapProducer getProducerInstance() {
/*if(mapFactory!=null)
return mapFactory.createMapProducer("text/html", null);*/
return new HTMLImageMapMapProducer();
}
/*public void testGetMapProducerFactory() throws Exception {
assertNotNull(mapFactory);
}*/
public void testGetMapProducer() throws Exception {
assertNotNull(mapProducer);
}
public DataStore getTestDataStore() throws IOException {
File testdata=TestData.file(this, "featureTypes");
return new MyPropertyDataStore(testdata);
}
public DataStore getProjectedTestDataStore() throws IOException {
File testdata=TestData.file(this, "featureTypes");
try {
return new MyPropertyDataStore(testdata,CRS.decode("EPSG:3004"));
} catch (NoSuchAuthorityCodeException e) {
e.printStackTrace();
return null;
} catch (FactoryException e) {
//
e.printStackTrace();
return null;
}
}
protected Style getTestStyle(String styleName) throws Exception {
SLDParser parser = new SLDParser(sFac);
File styleRes=TestData.file(this, "styles/"+styleName);
parser.setInput(styleRes);
Style s = parser.readXML()[0];
return s;
}
protected void assertTestResult(String testName, GetMapProducer producer) {
ByteArrayOutputStream out =null;
StringBuffer testText=new StringBuffer();
try {
out = new ByteArrayOutputStream();
producer.writeTo(out);
out.flush();
out.close();
File testFile=TestData.file(this, "results/"+testName+".txt");
BufferedReader reader=new BufferedReader(new FileReader(testFile));
String s=null;
while((s=reader.readLine())!=null)
testText.append(s+"\n");
reader.close();
} catch (Exception e) {
fail(e.getMessage());
}
assertNotNull(out);
assertTrue(out.size()>0);
String s = new String(out.toByteArray());
assertEquals(testText.toString(), s);
}
protected void assertNotBlank(String testName, GetMapProducer producer) {
ByteArrayOutputStream out =null;
try {
out = new ByteArrayOutputStream();
producer.writeTo(out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
assertNotNull(out);
assertTrue(out.size()>0);
String s=new String(out.toByteArray());
System.out.println(s);
}
public void testStates() throws Exception {
File shapeFile=TestData.file(this, "featureTypes/states.shp");
ShapefileDataStore ds=new ShapefileDataStore(shapeFile.toURL());
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = ds.getFeatureSource("states");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("Population.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("States", this.mapProducer);
}
public void testMapProduceBasicPolygons() throws Exception {
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("BasicPolygons");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
LOGGER.info("about to create map ctx for BasicPolygons with bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("default.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("BasicPolygons", this.mapProducer);
}
public void testMapProducePolygonsWithHoles() throws Exception {
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("PolygonWithHoles");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
LOGGER.info("about to create map ctx for BasicPolygons with bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("default.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("PolygonWithHoles", this.mapProducer);
}
public void testMapProducePolygonsWithSkippedHoles() throws Exception {
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("PolygonWithSkippedHoles");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
LOGGER.info("about to create map ctx for BasicPolygons with bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("default.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("PolygonWithSkippedHoles", this.mapProducer);
}
public void testMapProduceReproject() throws Exception {
final DataStore ds = getProjectedTestDataStore();
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = ds.getFeatureSource("ProjectedPolygon");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),CRS.decode("EPSG:3004"));
LOGGER.info("about to create map ctx for ProjectedPolygon with bounds " + env);
final WMSMapContext map = new WMSMapContext();
CoordinateReferenceSystem sourceCrs=CRS.decode("EPSG:3004");
CoordinateReferenceSystem targetCrs=CRS.decode("EPSG:3003");
MathTransform transform=CRS.findMathTransform(sourceCrs, targetCrs,true);
Envelope projEnv=JTS.transform(env, transform);
ReferencedEnvelope refEnv=new ReferencedEnvelope(projEnv,targetCrs);
map.setAreaOfInterest(refEnv);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setBgColor(Color.red);
map.setTransparent(false);
map.setCoordinateReferenceSystem(targetCrs);
Style basicStyle=getTestStyle("BasicPolygons.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("ProjectedPolygon", this.mapProducer);
}
public void testMapProduceLines() throws Exception {
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("RoadSegments");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
LOGGER.info("about to create map ctx for RoadSegments with bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("RoadSegments.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("RoadSegments", this.mapProducer);
}
public void testMapRuleWithFilters() throws Exception {
/*Filter f=filterFactory.equals(filterFactory.property("NAME"),filterFactory.literal("Route 5"));
DefaultQuery q=new DefaultQuery("RoadSegments",f);*/
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("RoadSegments");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
LOGGER.info("about to create map ctx for RoadSegments with filter on name and bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("RoadSegmentsFiltered.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("RoadSegmentsFiltered", this.mapProducer);
}
public void testMapProducePoints() throws Exception {
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("BuildingCenters");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
LOGGER.info("about to create map ctx for BuildingCenters with bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("BuildingCenters.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("BuildingCenters", this.mapProducer);
}
public void testMapProduceMultiPoints() throws Exception {
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("BuildingCentersMultiPoint");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
LOGGER.info("about to create map ctx for BuildingCentersMultiPoint with bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("BuildingCenters.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("BuildingCentersMultiPoint", this.mapProducer);
}
public void testMapProduceCollection() throws Exception {
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("CollectionSample");
final ReferencedEnvelope env = new ReferencedEnvelope(fs.getBounds(),WGS84);
LOGGER.info("about to create map ctx for RoadSegments with bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("CollectionSample.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("CollectionSample", this.mapProducer);
}
public void testMapProduceNoCoords() throws Exception {
final FeatureSource<SimpleFeatureType,SimpleFeature> fs = testDS.getFeatureSource("NoCoords");
final ReferencedEnvelope env = new ReferencedEnvelope(2.0,6.0,2.0,6.0,WGS84);
LOGGER.info("about to create map ctx for NamedPlaces with bounds " + env);
final WMSMapContext map = new WMSMapContext();
map.setAreaOfInterest(env);
map.setMapWidth(mapWidth);
map.setMapHeight(mapHeight);
map.setTransparent(false);
Style basicStyle = getTestStyle("NamedPlaces.sld");
map.addLayer(fs, basicStyle);
this.mapProducer.setOutputFormat("text/html");
this.mapProducer.setMapContext(map);
this.mapProducer.produceMap();
assertTestResult("NoCoords", this.mapProducer);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(HTMLImageMapTest.class);
}
static class MyPropertyDataStore extends PropertyDataStore {
CoordinateReferenceSystem myCRS=DefaultGeographicCRS.WGS84;
/**
* Creates a new MyPropertyDataStore object.
*
* @param dir DOCUMENT ME!
*/
public MyPropertyDataStore(File dir) {
super(dir);
}
/**
* Creates a new MyPropertyDataStore object.
*
* @param dir DOCUMENT ME!
*/
public MyPropertyDataStore(File dir,CoordinateReferenceSystem coordinateSystem) {
super(dir);
this.myCRS=coordinateSystem;
}
/**
* DOCUMENT ME!
*
* @param typeName DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws IOException DOCUMENT ME!
* @throws DataSourceException DOCUMENT ME!
*/
public SimpleFeatureType getSchema(String typeName) throws IOException {
SimpleFeatureType schema = super.getSchema(typeName);
try {
return DataUtilities.createSubType(schema, null, myCRS);
} catch (SchemaException e) {
throw new DataSourceException(e.getMessage(), e);
}
}
}
}