📄 kmlwriter.java
字号:
protected void writeGeometry(Geometry geom, GeometryTransformer trans)
throws IOException, TransformerException {
if (isMultiPart(geom)) {
for (int i = 0; i < geom.getNumGeometries(); i++) {
writeGeometry(geom.getGeometryN(i), trans);
}
} else {
// remove gml prefixing as KML does not accept them
StringWriter tempWriter = new StringWriter();
// trans.setNumDecimals(config.getNumDecimals());
trans.transform(geom, tempWriter);
String tempBuffer = tempWriter.toString();
// @REVISIT: should check which prefix is being used, this will only
// work for the default (99.9%) of cases.
write(tempBuffer.replaceAll("gml:", ""));
}
}
protected void writeLookAt(Geometry geom, GeometryTransformer trans)
throws IOException, TransformerException {
final Coordinate[] coordinates = getCentroid(geom).getCoordinates();
write("<LookAt>");
write("<longitude>" + coordinates[0].x + "</longitude>");
write("<latitude>" + coordinates[0].y + "</latitude>");
write("<range>700</range>");
write("<tilt>10.0</tilt>");
write("<heading>10.0</heading>");
write("</LookAt>");
}
protected void writePlaceMarkPoint(Geometry geom, GeometryTransformer trans)
throws IOException, TransformerException {
final Coordinate[] coordinates = getCentroid(geom).getCoordinates();
write("<Point><coordinates>" + coordinates[0].x + ","
+ coordinates[0].y + "," + coordinates[0].z
+ "</coordinates></Point>");
}
/**
* Test to see if the geometry is a Multi geometry
*
* @return true if geom instance of MultiPolygon, MultiPoint or
* MultiLineString
*/
protected boolean isMultiPart(Geometry geom) {
Class geomClass = geom.getClass();
return (geomClass.equals(MultiPolygon.class)
|| geomClass.equals(MultiPoint.class) || geomClass
.equals(MultiLineString.class));
}
/**
* Applies each feature type styler in turn to all of the features.
*
* @param features
* A FeatureCollection contatining the features to be rendered
* @param featureStylers
* An array of feature stylers to be applied
* @throws IOException
* @throws IllegalAttributeException
* @TODO: multiple features types result in muliple data passes, could be
* split into separate tempory files then joined.
*/
private void processStylersVector(final FeatureCollection features,
final FeatureTypeStyle[] featureStylers, final MapLayer layer)
throws IOException, IllegalAttributeException {
final int ftsLength = featureStylers.length;
for (int i = 0; i < ftsLength; i++) {
FeatureTypeStyle fts = featureStylers[i];
final String typeName = features.getSchema().getTypeName();
if ((typeName != null)
&& (features.getSchema().isDescendedFrom(null,
fts.getFeatureTypeName()) || typeName
.equalsIgnoreCase(fts.getFeatureTypeName()))) {
// get applicable rules at the current scale
Rule[] rules = fts.getRules();
List ruleList = new ArrayList();
List elseRuleList = new ArrayList();
populateRuleLists(rules, ruleList, elseRuleList, false);
if ((ruleList.size() == 0) && (elseRuleList.size() == 0)) {
return; // bail out early if no rules made it (because of
// scale denominators)
}
// REVISIT: once scaleDemominator can actualy be determined
// re-evaluate sensible ranges for GE
NumberRange scaleRange = new NumberRange(scaleDenominator,
scaleDenominator);
FeatureIterator reader = features.features();
while (true) {
try {
if (!reader.hasNext()) {
break;
}
boolean doElse = true;
Feature feature = reader.next();
StringBuffer featureLabel = new StringBuffer(""); // this
// gets
// filled
// in
// if
// there
// is a
// textsymbolizer
String id = feature.getID();
id = id.replaceAll("&", "");
id = id.replaceAll(">", "");
id = id.replaceAll("<", "");
id = id.replaceAll("%", "");
startDocument(id, layer.getTitle());
// start writing out the styles
write("<Style id=\"GeoServerStyle" + feature.getID()
+ "\">");
// applicable rules
for (Iterator it = ruleList.iterator(); it.hasNext();) {
Rule r = (Rule) it.next();
LOGGER.finer(new StringBuffer("applying rule: ")
.append(r.toString()).toString());
Filter filter = r.getFilter();
// if there is no filter or the filter says to do
// the feature anyways, render it
if ((filter == null) || filter.evaluate(feature)) {
doElse = false;
LOGGER.finer("processing Symobolizer ...");
Symbolizer[] symbolizers = r.getSymbolizers();
processVectorSymbolizers(feature, symbolizers,
scaleRange, featureLabel);
}
}
if (doElse) {
// rules with an else filter
LOGGER.finer("rules with an else filter");
for (Iterator it = elseRuleList.iterator(); it
.hasNext();) {
Rule r = (Rule) it.next();
Symbolizer[] symbolizers = r.getSymbolizers();
LOGGER.finer("processing Symobolizer ...");
processVectorSymbolizers(feature, symbolizers,
scaleRange, featureLabel);
}
}
write("</Style>"); // close off styles
// we have written out the style, so now lets write out
// the geometry
String fTitle = featureLabel.toString();
if (fTitle.equals("")) {
fTitle = feature.getID();
}
write("<Placemark>");
write("<name><![CDATA[" + featureLabel + "]]></name>"); // CDATA
// needed
// for
// ampersands
final FeatureType schema = features.getSchema();
// if there are supposed to be detailed descriptions,
// write them out
write("<description><![CDATA[");
writeDescription(feature, schema);
write("]]></description>");
writeLookAt(findGeometry(feature), transformer);
write("<styleUrl>#GeoServerStyle" + feature.getID()
+ "</styleUrl>");
write("<MultiGeometry>");
writePlaceMarkPoint(findGeometry(feature), transformer);
writeGeometry(findGeometry(feature), transformer);
write("</MultiGeometry>");
write("</Placemark>");
newline();
endDocument(); // </Document>
} catch (Exception e) {
// that feature failed but others may still work
// REVISIT: don't like eating exceptions, even with a
// log.
// e.printStackTrace();
LOGGER.warning(new StringBuffer(
"KML transform for feature failed ").append(
e.getMessage()).toString());
}
}
// FeatureIterators may be backed by a stream so this tidies
// things up.
features.close(reader);
}
}
}
/**
* Applies each feature type styler in turn to all of the features.
*
* @param features
* A FeatureCollection contatining the features to be rendered
* @param featureStylers
* An array of feature stylers to be applied
* @throws IOException
* @throws IllegalAttributeException
* @TODO: multiple features types result in muliple data passes, could be
* split into separate tempory files then joined.
*/
private void processStylersCoverage(final FeatureCollection features,
final FeatureTypeStyle[] featureStylers, final MapLayer layer)
throws IOException, IllegalAttributeException {
final int ftStylesLength = featureStylers.length;
for (int i = 0; i < ftStylesLength; i++) { // for each style
FeatureTypeStyle fts = featureStylers[i];
String typeName = features.getSchema().getTypeName();
if ((typeName != null)
&& (features.getSchema().isDescendedFrom(null,
fts.getFeatureTypeName()) || typeName
.equalsIgnoreCase(fts.getFeatureTypeName()))) {
// get applicable rules at the current scale
Rule[] rules = fts.getRules();
List ruleList = new ArrayList();
List elseRuleList = new ArrayList();
populateRuleLists(rules, ruleList, elseRuleList, false);
if ((ruleList.size() == 0) && (elseRuleList.size() == 0)) {
return;
}
FeatureIterator reader = features.features();
// we aren't going to iterate through the features because we
// just need to prepare
// the kml document for one feature; it is a raster result.
try {
if (!reader.hasNext()) {
continue; // no features, so move on
}
boolean doElse = true;
Feature feature = reader.next();
// applicable rules
for (Iterator it = ruleList.iterator(); it.hasNext();) {
Rule r = (Rule) it.next();
LOGGER.finer(new StringBuffer("applying rule: ")
.append(r.toString()).toString());
Filter filter = r.getFilter();
if ((filter == null) || filter.evaluate(feature)) {
doElse = false;
LOGGER
.finer("processing raster-result Symobolizer ...");
Symbolizer[] symbolizers = r.getSymbolizers();
processRasterSymbolizersForCoverage(feature,
symbolizers, layer);
}
}
if (doElse) {
// rules with an else filter
LOGGER.finer("rules with an else filter");
for (Iterator it = elseRuleList.iterator(); it
.hasNext();) {
Rule r = (Rule) it.next();
Symbolizer[] symbolizers = r.getSymbolizers();
LOGGER
.finer("processing raster-result Symobolizer ...");
processRasterSymbolizersForCoverage(feature,
symbolizers, layer);
}
}
} catch (Exception e) {
// that feature failed but others may still work
// REVISIT: don't like eating exceptions, even with a log.
LOGGER.warning(new StringBuffer(
"KML transform for feature failed ").append(
e.getMessage()).toString());
}
// FeatureIterators may be backed by a stream so this tidies
// things up.
features.close(reader);
} // end if
} // end for loop
}
/**
*
* @param features
* @param featureStylers
* @param layer
* @param order
* @throws IOException
* @throws IllegalAttributeException
*/
private void processStylersRaster(final FeatureCollection features,
final FeatureTypeStyle[] featureStylers, final MapLayer layer,
final int order) throws IOException, IllegalAttributeException {
startFolder("layer_" + order, layer.getTitle());
int layerCounter = order;
final int ftStylesLength = featureStylers.length;
for (int i = 0; i < ftStylesLength; i++) { // for each style
FeatureTypeStyle fts = featureStylers[i];
String typeName = features.getSchema().getTypeName();
if ((typeName != null)
&& (features.getSchema().isDescendedFrom(null,
fts.getFeatureTypeName()) || typeName
.equalsIgnoreCase(fts.getFeatureTypeName()))) {
// get applicable rules at the current scale
Rule[] rules = fts.getRules();
List ruleList = new ArrayList();
List elseRuleList = new ArrayList();
populateRuleLists(rules, ruleList, elseRuleList, true);
if ((ruleList.size() == 0) && (elseRuleList.size() == 0)) {
return;
}
FeatureIterator reader = features.features();
// we aren't going to iterate through the features because we
// just need to prepare
// the kml document for one feature; it is a raster result.
try {
if (!reader.hasNext()) {
continue; // no features, so move on
}
boolean doElse = true;
Feature feature = reader.next();
// applicable rules
for (Iterator it = ruleList.iterator(); it.hasNext();) {
Rule r = (Rule) it.next();
LOGGER.finer(new StringBuffer("applying rule: ")
.append(r.toString()).toString());
Filter filter = r.getFilter();
if ((filter == null) || filter.evaluate(feature)) {
doElse = false;
LOGGER
.finer("processing raster-result Symobolizer ...");
Symbolizer[] symbolizers = r.getSymbolizers();
processRasterSymbolizers(feature, symbolizers,
order);
layerCounter++;
}
}
if (doElse) {
// rules with an else filter
LOGGER.finer("rules with an else filter");
for (Iterator it = elseRuleList.iterator(); it
.hasNext();) {
Rule r = (Rule) it.next();
Symbolizer[] symbolizers = r.getSymbolizers();
LOGGER
.finer("processing raster-result Symobolizer ...");
processRasterSymbolizers(feature, symbolizers,
order);
layerCounter++;
}
}
} catch (Exception e) {
// that feature failed but others may still work
// REVISIT: don't like eating exceptions, even with a log.
LOGGER.warning(new StringBuffer(
"KML transform for feature failed ").append(
e.getMessage()).toString());
}
// FeatureIterators may be backed by a stream so this tidies
// things up.
features.close(reader);
} // end if
} // end for loop
endFolder(); // close the folder </Folder>
}
/**
* Sorts the rules into "If" rules and "Else" rules. The rules are sorted
* into their respective lists.
*
* @param rules
* @param ruleList
* @param elseRuleList
* @param ignoreScale
* ignore the scale denominator
*/
private void populateRuleLists(Rule[] rules, List ruleList,
List elseRuleList, boolean ignoreScale) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -