📄 kmlvectortransformer.java
字号:
}
}
} catch (Exception e) {
throw (IOException) new IOException().initCause(e);
}
}
/**
* Encodes a date as an xs:dateTime.
*/
protected String encodeDateTime( String date ) throws Exception {
//first try as date time
Date d = parseDate( dtformats, date );
if ( d == null ) {
//then try as date
d = parseDate( dformats, date );
}
if ( d == null ) {
//try as time
d = parseDate( tformats, date );
}
if ( d == null ) {
//last ditch effort, try to parse as xml dates
try {
//try as xml date time
d = DateUtil.deserializeDateTime( date );
}
catch( Exception e1 ) {
try {
//try as xml date
d = DateUtil.deserializeDate( date );
}
catch( Exception e2 ) {}
}
}
if ( d != null ) {
Calendar c = Calendar.getInstance();
c.setTime(d);
return new XSDateTimeBinding().encode( c , null );
}
LOGGER.warning("Could not parse date: " + date);
return null;
}
/**
* Parses a date as a string into a well-known format.
*/
protected Date parseDate( List formats, String date ) {
for ( Iterator f = formats.iterator(); f.hasNext(); ) {
SimpleDateFormat format = (SimpleDateFormat) f.next();
Date d = null;
try {
d = format.parse(date);
} catch (ParseException e) {}
if ( d != null ) {
return d;
}
}
return null;
}
/**
* Encodes a KML Placemark geometry from a geometry + centroid.
*/
protected void encodePlacemarkGeometry(Geometry geometry, Coordinate centroid) {
//if point, just encode a single point, otherwise encode the geometry
// + centroid
if ( geometry instanceof Point ||
(geometry instanceof MultiPoint) && ((MultiPoint)geometry).getNumPoints() == 1 ) {
encodeGeometry( geometry );
}
else {
start("MultiGeometry");
//the centroid
start("Point");
if (!Double.isNaN(centroid.z)) {
element("coordinates", centroid.x + "," + centroid.y + "," + centroid.z);
} else {
element("coordinates", centroid.x + "," + centroid.y);
}
end("Point");
//the actual geometry
encodeGeometry(geometry);
end("MultiGeometry");
}
}
/**
* Encodes a KML geometry.
*/
protected void encodeGeometry(Geometry geometry) {
if (geometry instanceof GeometryCollection) {
//unwrap the collection
GeometryCollection collection = (GeometryCollection) geometry;
for (int i = 0; i < collection.getNumGeometries(); i++) {
encodeGeometry(collection.getGeometryN(i));
}
} else {
geometryTranslator.encode(geometry);
}
}
/**
* Encodes a color element from its color + opacity representation.
*
* @param color The color to encode.
* @param opacity The opacity ( alpha ) of the color.
*/
void encodeColor(Color color, double opacity) {
encodeColor(colorToHex(color, opacity));
}
/**
* Encodes a color element from its hex representation.
*
* @param hex The hex value ( with alpha ) of the color.
*
*/
void encodeColor(String hex) {
element("color", hex);
}
/**
* Checks if a rule can be triggered at the current scale level
*
* @param r
* The rule
* @return true if the scale is compatible with the rule settings
*/
boolean isWithInScale(Rule r) {
return ((r.getMinScaleDenominator() - TOLERANCE) <= scaleDenominator)
&& ((r.getMaxScaleDenominator() + TOLERANCE) > scaleDenominator);
}
/**
* Returns the id of the feature removing special characters like
* '&','>','<','%'.
*/
String featureId(Feature feature) {
String id = feature.getID();
id = id.replaceAll("&", "");
id = id.replaceAll(">", "");
id = id.replaceAll("<", "");
id = id.replaceAll("%", "");
return id;
}
/**
* Rreturns the geometry for the feature reprojecting if necessary.
*/
Geometry featureGeometry(Feature f) {
// get the geometry
Geometry geom = f.getDefaultGeometry();
//rprojection done in KMLTransformer
// if (!CRS.equalsIgnoreMetadata(sourceCrs, mapContext.getCoordinateReferenceSystem())) {
// try {
// MathTransform transform = CRS.findMathTransform(sourceCrs,
// mapContext.getCoordinateReferenceSystem(), true);
// geom = JTS.transform(geom, transform);
// } catch (MismatchedDimensionException e) {
// LOGGER.severe(e.getLocalizedMessage());
// } catch (TransformException e) {
// LOGGER.severe(e.getLocalizedMessage());
// } catch (FactoryException e) {
// LOGGER.severe(e.getLocalizedMessage());
// }
// }
return geom;
}
/**
* Returns the centroid of the geometry, handling a geometry collection.
* <p>
* In the case of a collection a multi point containing the centroid of
* each geometry in the collection is calculated. The first point in
* the multi point is returned as the cetnroid.
* </p>
*/
Coordinate geometryCentroid(Geometry g) {
//TODO: should the collecftion case return the centroid of hte
// multi point?
if (g instanceof GeometryCollection) {
GeometryCollection gc = (GeometryCollection) g;
//check for case of single geometry
if ( gc.getNumGeometries() == 1 ) {
g = gc.getGeometryN(0);
}
else {
Coordinate[] pts = new Coordinate[gc.getNumGeometries()];
for (int t = 0; t < gc.getNumGeometries(); t++) {
pts[t] = gc.getGeometryN(t).getCentroid().getCoordinate();
}
return g.getFactory().createMultiPoint(pts).getCoordinates()[0];
}
}
if ( g instanceof Point ) {
//thats easy
return g.getCoordinate();
}
else if ( g instanceof LineString ) {
//make sure the point we return is actually on the line
double tol = 1E-6;
double mid = g.getLength() / 2d;
Coordinate[] coords = g.getCoordinates();
//walk along the linestring until we get to a point where we
// have two coordinates that straddle the midpoint
double len = 0d;
for ( int i = 1; i < coords.length; i++) {
LineSegment line = new LineSegment( coords[i-1],coords[i] );
len += line.getLength();
if ( Math.abs( len - mid ) < tol ) {
//close enough
return line.getCoordinate(1);
}
if ( len > mid ) {
//we have gone past midpoint
return line.pointAlong( 1 - ((len-mid)/line.getLength()) );
}
}
//should never get there
return g.getCentroid().getCoordinate();
}
else {
//return the actual centroid
return g.getCentroid().getCoordinate();
}
}
/**
* Utility method to convert an int into hex, padded to two characters.
* handy for generating colour strings.
*
* @param i Int to convert
* @return String a two character hex representation of i
* NOTE: this is a utility method and should be put somewhere more useful.
*/
String intToHex(int i) {
String prelim = Integer.toHexString(i);
if (prelim.length() < 2) {
prelim = "0" + prelim;
}
return prelim;
}
/**
* Utility method to convert a Color and opacity (0,1.0) into a KML
* color ref.
*
* @param c The color to convert.
* @param opacity Opacity / alpha, double from 0 to 1.0.
*
* @return A String of the form "#AABBGGRR".
*/
String colorToHex(Color c, double opacity) {
return new StringBuffer().append(intToHex(new Float(255 * opacity).intValue()))
.append(intToHex(c.getBlue())).append(intToHex(c.getGreen()))
.append(intToHex(c.getRed())).toString();
}
/**
* Filters the feature type styles of <code>style</code> returning only
* those that apply to <code>featureType</code>
* <p>
* This methods returns feature types for which
* <code>featureTypeStyle.getFeatureTypeName()</code> matches the name
* of the feature type of <code>featureType</code>, or matches the name of
* any parent type of the feature type of <code>featureType</code>. This
* method returns an empty array in the case of which no rules match.
* </p>
* @param style The style containing the feature type styles.
* @param featureType The feature type being filtered against.
*
*/
protected FeatureTypeStyle[] filterFeatureTypeStyles(Style style, FeatureType featureType) {
FeatureTypeStyle[] featureTypeStyles = style.getFeatureTypeStyles();
if ((featureTypeStyles == null) || (featureTypeStyles.length == 0)) {
return new FeatureTypeStyle[0];
}
ArrayList filtered = new ArrayList(featureTypeStyles.length);
for (int i = 0; i < featureTypeStyles.length; i++) {
FeatureTypeStyle featureTypeStyle = featureTypeStyles[i];
String featureTypeName = featureTypeStyle.getFeatureTypeName();
//does this style have any rules
if (featureTypeStyle.getRules() == null || featureTypeStyle.getRules().length == 0 ) {
continue;
}
//does this style apply to the feature collection
if (featureType.getTypeName().equalsIgnoreCase(featureTypeName)
|| featureType.isDescendedFrom(null, featureTypeName)) {
filtered.add(featureTypeStyle);
}
}
return (FeatureTypeStyle[]) filtered.toArray(new FeatureTypeStyle[filtered.size()]);
}
/**
* Filters the rules of <code>featureTypeStyle</code> returnting only
* those that apply to <code>feature</code>.
* <p>
* This method returns rules for which:
* <ol>
* <li><code>rule.getFilter()</code> matches <code>feature</code>, or:
* <li>the rule defines an "ElseFilter", and the feature matches no
* other rules.
* </ol>
* This method returns an empty array in the case of which no rules
* match.
* </p>
* @param featureTypeStyle The feature type style containing the rules.
* @param feature The feature being filtered against.
*
*/
Rule[] filterRules(FeatureTypeStyle featureTypeStyle, Feature feature) {
Rule[] rules = featureTypeStyle.getRules();
if ((rules == null) || (rules.length == 0)) {
return new Rule[0];
}
ArrayList filtered = new ArrayList(rules.length);
//process the rules, keep track of the need to apply an else filters
boolean match = false;
boolean hasElseFilter = false;
for (int i = 0; i < rules.length; i++) {
Rule rule = rules[i];
LOGGER.finer(new StringBuffer("Applying rule: ").append(rule.toString()).toString());
//does this rule have an else filter
if (rule.hasElseFilter()) {
hasElseFilter = true;
continue;
}
//is this rule within scale?
if ( !isWithInScale(rule)) {
continue;
}
//does this rule have a filter which applies to the feature
Filter filter = rule.getFilter();
if ((filter == null) || filter.evaluate(feature)) {
match = true;
filtered.add(rule);
}
}
//if no rules mached the feautre, re-run through the rules applying
// any else filters
if (!match && hasElseFilter) {
//loop through again and apply all the else rules
for (int i = 0; i < rules.length; i++) {
Rule rule = rules[i];
if (rule.hasElseFilter()) {
filtered.add(rule);
}
}
}
return (Rule[]) filtered.toArray(new Rule[filtered.size()]);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -