Skip to content

Commit

Permalink
getmap works for the geometry now, need to test with a background
Browse files Browse the repository at this point in the history
  • Loading branch information
Jesse Eichar committed Nov 13, 2012
1 parent 2475a2a commit e0822c8
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 59 deletions.
140 changes: 88 additions & 52 deletions web/src/main/java/org/fao/geonet/services/region/GetMap.java
Expand Up @@ -23,15 +23,17 @@

package org.fao.geonet.services.region;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

import jeeves.constants.Jeeves;
import jeeves.interfaces.Service;
Expand All @@ -43,11 +45,13 @@
import org.fao.geonet.constants.Params;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.referencing.operation.transform.AffineTransform2D;
import org.jdom.Element;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;

import com.vividsolutions.jts.awt.ShapeWriter;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;

//=============================================================================
Expand All @@ -62,6 +66,7 @@ public class GetMap implements Service {
public static final String HEIGHT_PARAM = "HEIGHT";
public static final String BACKGROUND_PARAM = "BACKGROUND";
private String format;

public void init(String appPath, ServiceConfig params) throws Exception {
this.format = params.getMandatoryValue("format");
}
Expand All @@ -72,56 +77,87 @@ public void init(String appPath, ServiceConfig params) throws Exception {
// ---
// --------------------------------------------------------------------------

public Element exec(Element params, ServiceContext context) throws Exception
{
String id = params.getChildText(Params.ID);
String srs = Util.getParam(params, SRS_PARAM, "EPSG:4326");
int width = Util.getParamAsInt(params, WIDTH_PARAM);
int height = Util.getParamAsInt(params, HEIGHT_PARAM);
String background = params.getChildText(BACKGROUND_PARAM);

if (id == null)
return new Element(Jeeves.Elem.RESPONSE);

RegionsDAO dao = context.getApplicationContext().getBean(RegionsDAO.class);
Geometry region = dao.getGeom(context, id, false);
if (!srs.equalsIgnoreCase((String) region.getUserData())) {
CoordinateReferenceSystem geometryCRS = CRS.decode((String) region.getUserData());
CoordinateReferenceSystem desiredCRS = CRS.decode(srs);
if (!CRS.equalsIgnoreMetadata(geometryCRS, desiredCRS)) {
MathTransform transform = CRS.findMathTransform(geometryCRS, desiredCRS, true);
region = JTS.transform(region, transform );
}
}
if (region == null) {
throw new RegionNotFoundEx(id);
}

BufferedImage image;
if (background != null) {
URL imageUrl = new URL(background);
InputStream in = imageUrl.openStream();
try {
image = ImageIO.read(in);
} finally {
in.close();

}
} else {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
}

Graphics2D graphics = image.createGraphics();
try {
ShapeWriter shapeWriter = new ShapeWriter();
graphics.draw(shapeWriter.toShape(region));
} finally {
graphics.dispose();
}
File tmpFile = File.createTempFile("GetMap", format);
ImageIO.write(image, "image/"+format, tmpFile );
return BinaryFile.encode(200, tmpFile.getAbsolutePath(), true);
}
public Element exec(Element params, ServiceContext context) throws Exception {
String id = params.getChildText(Params.ID);
String srs = Util.getParam(params, SRS_PARAM, "EPSG:4326");
int width = Util.getParamAsInt(params, WIDTH_PARAM);
int height = Util.getParamAsInt(params, HEIGHT_PARAM);
String background = params.getChildText(BACKGROUND_PARAM);

if (id == null)
return new Element(Jeeves.Elem.RESPONSE);

RegionsDAO dao = context.getApplicationContext().getBean(RegionsDAO.class);
Geometry region = dao.getGeom(context, id, false);
CoordinateReferenceSystem geometryCRS = (CoordinateReferenceSystem) region.getUserData();
CoordinateReferenceSystem desiredCRS = CRS.decode(srs);
if (!CRS.equalsIgnoreMetadata(geometryCRS, desiredCRS)) {
MathTransform transform = CRS.findMathTransform(geometryCRS, desiredCRS, true);
region = JTS.transform(region, transform);
}
if (region == null) {
throw new RegionNotFoundEx(id);
}

BufferedImage image;
Envelope bboxOfImage = new Envelope(region.getEnvelopeInternal());
double expandFactor = 0.2;
bboxOfImage.expandBy(bboxOfImage.getWidth() * expandFactor, bboxOfImage.getHeight() * expandFactor);
if (background != null) {

String minx = Double.toString(bboxOfImage.getMinX());
String maxx = Double.toString(bboxOfImage.getMaxX());
String miny = Double.toString(bboxOfImage.getMinY());
String maxy = Double.toString(bboxOfImage.getMaxY());
background.replace("{minx}", minx).replace("{maxx}", maxx).replace("{miny}", miny).replace("{maxy}", maxy)
.replace("{width}", Integer.toString(width)).replace("{height}", Integer.toString(height));

URL imageUrl = new URL(background);
InputStream in = imageUrl.openStream();
try {
image = ImageIO.read(in);
} finally {
in.close();

}
} else {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}

Graphics2D graphics = image.createGraphics();
try {
ShapeWriter shapeWriter = new ShapeWriter();
AffineTransform worldToScreenTransform = worldToScreenTransform(bboxOfImage, new Dimension(width, height));
MathTransform mathTransform = new AffineTransform2D(worldToScreenTransform);
Geometry screenGeom = JTS.transform(region, mathTransform);
Shape shape = shapeWriter.toShape(screenGeom);
graphics.setColor(Color.yellow);
graphics.draw(shape);

graphics.setColor(new Color(255,255,0,100));
graphics.fill(shape);

} finally {
graphics.dispose();
}

File tmpFile = File.createTempFile("GetMap", "."+format);
ImageIO.write(image, format, tmpFile);
return BinaryFile.encode(200, tmpFile.getAbsolutePath(), true);
}

public static AffineTransform worldToScreenTransform(Envelope mapExtent, Dimension screenSize) {
double scaleX = screenSize.getWidth() / mapExtent.getWidth();
double scaleY = screenSize.getHeight() / mapExtent.getHeight();

double tx = -mapExtent.getMinX() * scaleX;
double ty = (mapExtent.getMinY() * scaleY) + screenSize.getHeight();

AffineTransform at = new AffineTransform(scaleX, 0.0d, 0.0d, -scaleY, tx, ty);

return at;
}

}

// =============================================================================
Expand Down
Expand Up @@ -12,15 +12,15 @@ public interface RegionsDAO {
Request createSearchRequest(ServiceContext context) throws Exception;

/**
* Get the geometry object for the region. The srs code must be available with the geometry's getUserData()
* Get the geometry object for the region. The CRS must be available with the geometry's getUserData()
* method.
* @param context
* @param id id of the region ot fetch
* @param simplified a hint to simplify the geometry if the full geometry is very large. This will
* be true when the UI wants to display the geometry. The region is simplified so the javascript can deal with it better
* and so it downloads faster.
*
* @return the geometry containing the srs code
* @return the geometry containing the CRS
*/
Geometry getGeom(ServiceContext context, String id, boolean simplified) throws Exception;

Expand Down
Expand Up @@ -58,7 +58,9 @@ public Geometry getGeom(ServiceContext context, String id, boolean simplified) t
return null;
}

return factory.toGeometry(region.getBBox());
Geometry geometry = factory.toGeometry(region.getBBox());
geometry.setUserData(region.getBBox().getCoordinateReferenceSystem());
return geometry;
}

}
2 changes: 1 addition & 1 deletion web/src/main/webapp/WEB-INF/config-security-mapping.xml
Expand Up @@ -357,7 +357,7 @@ xsi:schemaLocation="http://www.springframework.org/schema/beans
<!-- Region services -->
<sec:intercept-url pattern="/srv/.*/xml.region.get!?.*" access="permitAll"></sec:intercept-url>
<sec:intercept-url pattern="/srv/.*/xml.regions.list!?.*" access="permitAll"></sec:intercept-url>
<sec:intercept-url pattern="/srv/.*/region.getmap!?.*" access="permitAll"></sec:intercept-url>
<sec:intercept-url pattern="/srv/.*/region.getmap.png!?.*" access="permitAll"></sec:intercept-url>
<sec:intercept-url pattern="/srv/.*/wkt.region.geom!?.*" access="permitAll"></sec:intercept-url>


Expand Down
6 changes: 3 additions & 3 deletions web/src/main/webapp/WEB-INF/config.xml
Expand Up @@ -633,11 +633,11 @@
<class name=".services.region.List" />
</service>

<service name="pdf.region.getmap">
<service name="region.getmap.png">
<class name=".services.region.GetMap" >
<param name="format" value="pdf"/>
<param name="format" value="png"/>
</class>
<output file="true" contentType="image/pdf"/>
<output file="true" contentType="image/png"/>
<error id="region-not-found" sheet="error-embedded.xsl" statusCode="404">
<xml name="error" file="xml/file-not-found-error.xml" />
</error>
Expand Down

0 comments on commit e0822c8

Please sign in to comment.