📄 kmltransformer.java
字号:
}
} else {
//kmz not selected, just do straight vector
KMLVectorTransformer tx = createVectorTransformer(mapContext, layer);
initTransformer(tx);
tx.setScaleDenominator(scaleDenominator);
tx.createTranslator(contentHandler).encode(features);
}
}
/**
* Factory method, allows subclasses to inject their own version of the raster transfomer
* @param mapContext
* @return
*/
protected KMLRasterTransformer createRasterTransfomer(WMSMapContext mapContext) {
return new KMLRasterTransformer(mapContext);
}
/**
* Factory method, allows subclasses to inject their own version of the vector transfomer
* @param mapContext
* @return
*/
protected KMLVectorTransformer createVectorTransformer(WMSMapContext mapContext,
MapLayer layer) {
return new KMLVectorTransformer(mapContext, layer);
}
/**
* Encodes a raster layer as kml.
*/
protected void encodeRasterLayer(WMSMapContext mapContext, MapLayer layer) {
KMLRasterTransformer tx = createRasterTransfomer(mapContext);
initTransformer(tx);
tx.setInline(kmz);
tx.createTranslator(contentHandler).encode(layer);
}
/**
* Encodes a layer as a super overlay.
*/
protected void encodeSuperOverlayLayer(WMSMapContext mapContext, MapLayer layer) {
KMLSuperOverlayTransformer tx = new KMLSuperOverlayTransformer(mapContext);
initTransformer(tx);
tx.createTranslator(contentHandler).encode(layer);
}
/**
* Encodes the legend for a maper layer as a scree overlay.
*/
protected void encodeLegend(WMSMapContext mapContext, MapLayer layer) {
KMLLegendTransformer tx = new KMLLegendTransformer(mapContext);
initTransformer(tx);
tx.createTranslator(contentHandler).encode(layer);
}
protected void initTransformer(KMLTransformerBase delegate) {
delegate.setIndentation( getIndentation() );
delegate.setStandAlone(false);
}
double computeScaleDenominator(MapLayer layer, WMSMapContext mapContext) {
Rectangle paintArea = new Rectangle(mapContext.getMapWidth(), mapContext.getMapHeight());
AffineTransform worldToScreen = RendererUtilities.worldToScreenTransform(mapContext
.getAreaOfInterest(), paintArea);
try {
//90 = OGC standard DPI (see SLD spec page 37)
return RendererUtilities.calculateScale(mapContext.getAreaOfInterest(),
mapContext.getCoordinateReferenceSystem(), paintArea.width, paintArea.height, 90);
} catch (Exception e) {
//probably either (1) no CRS (2) error xforming, revert to
// old method - the best we can do (DJB)
return 1 / worldToScreen.getScaleX();
}
}
/**
* Determines whether to return a vector (KML) result of the data or to
* return an image instead.
* If the kmscore is 100, then the output should always be vector. If
* the kmscore is 0, it should always be raster. In between, the number of
* features is weighed against the kmscore value.
* kmscore determines whether to return the features as vectors, or as one
* raster image. It is the point, determined by the user, where X number of
* features is "too many" and the result should be returned as an image instead.
*
* kmscore is logarithmic. The higher the value, the more features it takes
* to make the algorithm return an image. The lower the kmscore, the fewer
* features it takes to force an image to be returned.
* (in use, the formula is exponential: as you increase the KMScore value,
* the number of features required increases exponentially).
*
* @param kmscore the score, between 0 and 100, use to determine what output to use
* @param numFeatures how many features are being rendered
* @return true: use just kml vectors, false: use raster result
*/
boolean useVectorOutput(int kmscore, int numFeatures) {
if (kmscore == 100) {
return true; // vector KML
}
if (kmscore == 0) {
return false; // raster KMZ
}
// For numbers in between, determine exponentionally based on kmscore value:
// 10^(kmscore/15)
// This results in exponential growth.
// The lowest bound is 1 feature and the highest bound is 3.98 million features
// The most useful kmscore values are between 20 and 70 (21 and 46000 features respectively)
// A good default kmscore value is around 40 (464 features)
double magic = Math.pow(10, kmscore / 15);
if (numFeatures > magic) {
return false; // return raster
} else {
return true; // return vector
}
}
FeatureCollection loadFeatureCollection(FeatureSource featureSource, MapLayer layer,
WMSMapContext mapContext) throws Exception {
FeatureType schema = featureSource.getSchema();
Envelope envelope = mapContext.getAreaOfInterest();
ReferencedEnvelope aoi = new ReferencedEnvelope(envelope,
mapContext.getCoordinateReferenceSystem());
CoordinateReferenceSystem sourceCrs = schema.getDefaultGeometry().getCoordinateSystem();
boolean reprojectBBox = (sourceCrs != null)
&& !CRS.equalsIgnoreMetadata(aoi.getCoordinateReferenceSystem(), sourceCrs);
if (reprojectBBox) {
aoi = aoi.transform(sourceCrs, true);
}
Filter filter = createBBoxFilter(schema, aoi);
// now build the query using only the attributes and the bounding
// box needed
DefaultQuery q = new DefaultQuery(schema.getTypeName());
q.setFilter(filter);
// 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");
}
}
// make sure we output in 4326 since that's what KML mandates
if (sourceCrs != null && !CRS.equalsIgnoreMetadata(WGS84, sourceCrs)) {
return new ReprojectFeatureResults( featureSource.getFeatures(q), WGS84 );
}
return featureSource.getFeatures(q);
}
/** 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 bbox the expression holding the target 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
*/
Filter createBBoxFilter(FeatureType schema, Envelope bbox)
throws IllegalFilterException {
List filters = new ArrayList();
for (int j = 0; j < schema.getAttributeCount(); j++) {
AttributeType attType = schema.getAttributeType(j);
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 + -