📄 encodekml.java
字号:
double scaleDenominator = 1;
try {
scaleDenominator = RendererUtilities.calculateScale(mapContext.getAreaOfInterest(),
mapContext.getCoordinateReferenceSystem(), paintArea.width,
paintArea.height, 90); // 90 = OGC standard DPI (see SLD spec page 37)
} catch (Exception e) // probably either (1) no CRS (2) error xforming
{
scaleDenominator = 1 / worldToScreen.getScaleX(); //DJB old method - the best we can do
}
writer.setRequestedScale(scaleDenominator);
String[] attributes;
boolean isRaster = false;
AttributeType[] ats = schema.getAttributeTypes();
final int length = ats.length;
attributes = new String[length];
for (int t = 0; t < length; t++) {
attributes[t] = ats[t].getName();
if (attributes[t].equals("grid")) {
isRaster = true;
}
}
try {
CoordinateReferenceSystem sourceCrs = schema.getDefaultGeometry()
.getCoordinateSystem();
writer.setSourceCrs(sourceCrs); // it seems to work better getting it from the schema, here
Envelope envelope = mapContext.getAreaOfInterest();
ReferencedEnvelope aoi = new ReferencedEnvelope(envelope,
mapContext.getCoordinateReferenceSystem());
Filter filter = null;
//ReferencedEnvelope aoi = mapContext.getAreaOfInterest();
if (!CRS.equalsIgnoreMetadata(aoi.getCoordinateReferenceSystem(),
schema.getDefaultGeometry().getCoordinateSystem())) {
aoi = aoi.transform(schema.getDefaultGeometry().getCoordinateSystem(), true);
}
filter = createBBoxFilters(schema, attributes, aoi);
// now build the query using only the attributes and the bounding
// box needed
DefaultQuery q = new DefaultQuery(schema.getTypeName());
q.setFilter(filter);
q.setPropertyNames(attributes);
// now, if a definition query has been established for this layer, be
// sure to respect it by combining it with the bounding box one.
Query definitionQuery = layer.getQuery();
if (definitionQuery != Query.ALL) {
if (q == Query.ALL) {
q = (DefaultQuery) definitionQuery;
} else {
q = (DefaultQuery) DataUtilities.mixQueries(definitionQuery, q, "KMLEncoder");
}
}
q.setCoordinateSystem(layer.getFeatureSource().getSchema().getDefaultGeometry()
.getCoordinateSystem());
FeatureCollection fc = fSource.getFeatures(q);
int kmscore = mapContext.getRequest().getKMScore(); //KMZ score value
boolean useVector = useVectorOutput(kmscore, fc.size()); // kmscore = render vector/raster
if (useVector || !kmz) {
LOGGER.info("Layer (" + layer.getTitle() + ") rendered with KML vector output.");
layerRenderList.add(new Integer(i)); // save layer number so it won't be rendered
if (!isRaster) {
writer.writeFeaturesAsVectors(fc, layer); // vector
} else {
writer.writeCoverages(fc, layer); // coverage
}
} else {
// user requested KMZ and kmscore says render raster
LOGGER.info("Layer (" + layer.getTitle() + ") rendered with KMZ raster output.");
// layer order is only needed for raster results. In the <GroundOverlay> tag
// you need to point to a raster image, this image has the layer number as
// part of the name. The kml will then reference the image via the layer number
writer.writeFeaturesAsRaster(fc, layer, i); // raster
}
LOGGER.fine("finished writing");
} catch (IOException ex) {
LOGGER.info(new StringBuffer("process failed: ").append(ex.getMessage()).toString());
throw ex;
} catch (AbortedException ae) {
LOGGER.info(new StringBuffer("process aborted: ").append(ae.getMessage()).toString());
throw ae;
} catch (Throwable t) {
LOGGER.warning(new StringBuffer("UNCAUGHT exception: ").append(t.getMessage())
.toString());
IOException ioe = new IOException(new StringBuffer("UNCAUGHT exception: ").append(
t.getMessage()).toString());
ioe.setStackTrace(t.getStackTrace());
throw ioe;
} finally {
/*if (featureReader != null) {
try{
featureReader.close();
}catch(IOException ioe){
//featureReader was probably closed already.
}
}*/
}
writer.endDocument();
}
if (nLayers > 1) {
writer.endDocument();
}
}
/**
* This method produces and stores PNG images of all map layers using the StreamingRenderer and JAI Encoder.
*
* @param outZ
* @throws IOException
* @throws AbortedException
*/
private void writeImages(final ZipOutputStream outZ, ArrayList layerRenderList)
throws IOException, AbortedException {
MapLayer[] layers = this.mapContext.getLayers();
int nLayers = layers.length;
for (int i = 0; i < nLayers; i++) {
if (layerRenderList.size() > 0) {
int num = ((Integer) layerRenderList.get(0)).intValue();
if (num == i) { // if this layer is a layer that doesn't need to be rendered, move to next layer
layerRenderList.remove(0);
continue;
}
}
final MapLayer layer = layers[i];
MapContext map = this.mapContext;
map.clearLayerList();
map.addLayer(layer);
final int width = this.mapContext.getMapWidth();
final int height = this.mapContext.getMapHeight();
LOGGER.fine(new StringBuffer("setting up ").append(width).append("x").append(height)
.append(" image").toString());
// simone: ARGB should be much better
BufferedImage curImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
// simboss: this should help out with coverages
final Graphics2D graphic = GraphicsJAI.createGraphicsJAI(curImage.createGraphics(), null);
LOGGER.fine("setting to transparent");
int type = AlphaComposite.SRC;
graphic.setComposite(AlphaComposite.getInstance(type));
Color c = new Color(this.mapContext.getBgColor().getRed(),
this.mapContext.getBgColor().getGreen(),
this.mapContext.getBgColor().getBlue(), 0);
//LOGGER.info("****** bg color: "+c.getRed()+","+c.getGreen()+","+c.getBlue()+","+c.getAlpha()+", trans: "+c.getTransparency());
graphic.setBackground(this.mapContext.getBgColor());
graphic.setColor(c);
graphic.fillRect(0, 0, width, height);
type = AlphaComposite.SRC_OVER;
graphic.setComposite(AlphaComposite.getInstance(type));
Rectangle paintArea = new Rectangle(width, height);
final StreamingRenderer renderer = new StreamingRenderer();
renderer.setContext(map);
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
renderer.setJava2DHints(hints);
// we already do everything that the optimized data loading does...
// if we set it to true then it does it all twice...
Map rendererParams = new HashMap();
rendererParams.put("optimizedDataLoadingEnabled", Boolean.TRUE);
rendererParams.put("renderingBuffer", new Integer(mapContext.getBuffer()));
renderer.setRendererHints(rendererParams);
Envelope dataArea = map.getAreaOfInterest();
AffineTransform at = RendererUtilities.worldToScreenTransform(dataArea, paintArea);
renderer.paint(graphic, paintArea, dataArea, at);
graphic.dispose();
// /////////////////////////////////////////////////////////////////
//
// Storing Image ...
//
// /////////////////////////////////////////////////////////////////
final ZipEntry e = new ZipEntry("layer_" + (i) + ".png");
outZ.putNextEntry(e);
new ImageWorker(curImage).writePNG(outZ, "FILTERED", 0.75f, false, false);
//final MemoryCacheImageOutputStream memOutStream = new MemoryCacheImageOutputStream(outZ);
/*final PlanarImage encodedImage = PlanarImage
.wrapRenderedImage(curImage);
//final PlanarImage finalImage = encodedImage.getColorModel() instanceof DirectColorModel?ImageUtilities
// .reformatColorModel2ComponentColorModel(encodedImage):encodedImage;
final PlanarImage finalImage = encodedImage;
final Iterator it = ImageIO.getImageWritersByMIMEType("image/png");
ImageWriter imgWriter = null;
if (!it.hasNext()) {
LOGGER.warning("No PNG ImageWriter found");
throw new IllegalStateException("No PNG ImageWriter found");
} else
imgWriter = (ImageWriter) it.next();
*/
//---------------------- bo- new
// PngEncoderB png = new PngEncoderB(curImage, PngEncoder.ENCODE_ALPHA, 0, 1);
// byte[] pngbytes = png.pngEncode();
// memOutStream.write(pngbytes);
//----------------------
//imgWriter.setOutput(memOutStream);
//imgWriter.write(null, new IIOImage(finalImage, null, null), null);
//memOutStream.flush();
//memOutStream.close();
//imgWriter.dispose();
outZ.closeEntry();
}
}
/**
* Creates the bounding box filters (one for each geometric attribute) needed to query a
* <code>MapLayer</code>'s feature source to return just the features for the target
* rendering extent
*
* @param schema the layer's feature source schema
* @param attributes set of needed attributes
* @param bbox the rendering bounding box
* @return an or'ed list of bbox filters, one for each geometric attribute in
* <code>attributes</code>. If there are just one geometric attribute, just returns
* its corresponding <code>GeometryFilter</code>.
* @throws IllegalFilterException if something goes wrong creating the filter
*/
private Filter createBBoxFilters(FeatureType schema, String[] attributes, Envelope bbox)
throws IllegalFilterException {
List filters = new ArrayList();
final int length = attributes.length;
for (int j = 0; j < length; j++) {
AttributeType attType = schema.getAttributeType(attributes[j]);
//DJB: added this for better error messages!
if (attType == null) {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine(new StringBuffer("Could not find '").append(attributes[j])
.append("' in the FeatureType (")
.append(schema.getTypeName())
.append(")").toString());
}
throw new IllegalFilterException(new StringBuffer("Could not find '").append(attributes[j]
+ "' in the FeatureType (").append(schema.getTypeName()).append(")")
.toString());
}
if (attType instanceof GeometryAttributeType) {
Filter gfilter = filterFactory.bbox(attType.getLocalName(), bbox.getMinX(), bbox.getMinY(), bbox.getMaxX(), bbox.getMaxY(), null);
filters.add(gfilter);
}
}
if(filters.size() == 0)
return Filter.INCLUDE;
else if(filters.size() == 1)
return (Filter) filters.get(0);
else
return filterFactory.or(filters);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -