// itterate through the the FeatureSources to release the locks
//
WFS wfs = request.getWFS();
GeoServer config = wfs.getGeoServer();
Data catalog = wfs.getData();
FeatureTypeInfo meta = null;
NameSpaceInfo namespace;
Query query;
FeatureSource source;
Feature feature;
String fid;
FilterFactory filterFactory = FilterFactoryFinder.createFilterFactory();
FidFilter fidFilter;
try {
for (Iterator it = request.getQueries().iterator(); it.hasNext();) {
query = (Query) it.next();
// the feature type name used in the content disposition response will match
// the first feature type
if (featureTypeName == null) {
featureTypeName = query.getTypeName();
}
meta = catalog.getFeatureTypeInfo(query.getTypeName());
namespace = meta.getDataStoreInfo().getNameSpace();
source = meta.getFeatureSource();
List attrs = meta.getAttributes();
List propNames = query.getPropertyNames(); // REAL LIST: be careful here :)
List attributeNames = meta.getAttributeNames();
for (Iterator iter = propNames.iterator(); iter.hasNext();) {
String propName = (String) iter.next();
if (!attributeNames.contains(propName)) {
String mesg = "Requested property: " + propName + " is "
+ "not available for " + query.getTypeName() + ". "
+ "The possible propertyName values are: " + attributeNames;
throw new WfsException(mesg);
}
}
List extraGeometries = new ArrayList();
List properties = new ArrayList();
if (propNames.size() != 0) {
Iterator ii = attrs.iterator();
while (ii.hasNext()) {
AttributeTypeInfo ati = (AttributeTypeInfo) ii.next();
//String attName = (String) ii.next();
LOGGER.finer("checking to see if " + propNames + " contains" + ati);
if (((ati.getMinOccurs() > 0) && (ati.getMaxOccurs() != 0))
|| propNames.contains(ati.getName())) {
properties.add(ati.getName());
}
//if(wfs.isFeatureBounding() && meta.getFeatureType().getAttributeType(ati.getName()) instanceof GeometryAttributeType
// && !properties.contains(ati.getName())) {
// properties.add(ati.getName());
// extraGeometries.add(ati.getName());
//}
if(meta.getFeatureType().getAttributeType(ati.getName()) instanceof GeometryAttributeType
&& !properties.contains(ati.getName())) {
properties.add(ati.getName());
extraGeometries.add(ati.getName());
}
}
query.setPropertyNames(properties);
}
// Add range to filter
AttributeExpression geomAttb = filterFactory.createAttributeExpression(meta.getFeatureType(), meta.getFeatureType().getDefaultGeometry().getName());
LiteralExpression pointExpr = filterFactory.createLiteralExpression(request.getPoint());
DWithin dWithin = filterFactory.dwithin(geomAttb, pointExpr, request.getMaxRange(), request.getUnits());
if (query.getFilter() == null) {
query.addFilter((Filter)dWithin);
} else {
And andFilter = filterFactory.and(Arrays.asList(new Filter[] { (Filter)dWithin, query.getFilter() }));
query.addFilter((Filter)andFilter);
}
LOGGER.fine("Query is " + query + "\n To gt2: " + query.toDataQuery(Integer.MAX_VALUE));
//DJB: note if maxFeatures gets to 0 the while loop above takes care of this! (this is a subtle situation)
FeatureCollection featuresCheck = source.getFeatures(query.toDataQuery(Integer.MAX_VALUE));
// find nearest feature
Unit fromUnit = SI.METER;
Unit toUnit = UnitFormat.getInstance().parseUnit(request.getUnits());
Converter unitConvert = fromUnit.getConverterTo(toUnit);
Feature nearestFeature = null;
double nearestDistance = 9e9;
double nearestBearing = 0;
for (Iterator sItr = featuresCheck.iterator(); sItr.hasNext();) {
Feature f = (Feature)sItr.next();
if (f.getDefaultGeometry() == null) continue;
DistanceOp op = new DistanceOp(request.getPoint(), f.getDefaultGeometry());
Coordinate[] co = op.closestPoints();
Measure m = DefaultGeographicCRS.WGS84.distance(new double[] { co[0].x, co[0].y, }, new double[] { co[1].x, co[1].y, });
if (m.doubleValue() > nearestDistance) continue;
nearestFeature = f;
nearestDistance = m.doubleValue();
nearestBearing = calcBearing(co);
}
//GR: I don't know if the featuresults should be added here for later
//encoding if it was a lock request. may be after ensuring the lock
//succeed?
FeatureCollection features = FeatureCollections.newCollection();
if (nearestFeature != null) features.add(superFeature(nearestFeature, unitConvert.convert(nearestDistance), nearestBearing));
// we may need to shave off geometries we did load only to make bounds
// computation happy
if(extraGeometries.size() > 0) {
List residualProperties = new ArrayList(properties);
residualProperties.removeAll(extraGeometries);
residualProperties.add("nearest_distance");
residualProperties.add("nearest_bearing");
String[] residualNames = (String[]) residualProperties.toArray(new String[residualProperties.size()]);
FeatureType targetType = DataUtilities.createSubType(superFeatureType(meta.getFeatureType()), residualNames);
features = new FeatureBoundsFeatureCollection(features, targetType);
}
results.addFeatures(meta, features);
}