/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.kml.regionate;
import java.util.Map;
import java.util.logging.Level;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.config.GeoServer;
import org.geoserver.platform.ServiceException;
import org.geoserver.wms.MapLayerInfo;
import org.geoserver.wms.WMSMapContent;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeType;
import org.opengis.feature.type.FeatureType;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.MultiPolygon;
import com.vividsolutions.jts.geom.Polygon;
/**
* Strategy using geometry size to determine feature allocation in tiles. Bigger
* geometries get into the bigger tiles. Does not work with simple points, use
* attribute sorting or random strategy in that case
*
* @author Andrea Aime
*/
public class GeometryRegionatingStrategy extends
ExternalSortRegionatingStrategy {
public GeometryRegionatingStrategy(GeoServer gs) {
super(gs);
}
@Override
protected void checkAttribute(WMSMapContent con, SimpleFeatureType ft) {
// find out which attribute we're going to use
Map options = con.getRequest().getFormatOptions();
attribute = (String) options.get("regionateAttr");
if (attribute == null) {
attribute = MapLayerInfo.getRegionateAttribute(featureType);
}
if (attribute == null || ft.getDescriptor(attribute) == null) {
LOGGER.log(Level.FINER, "No attribute specified, falling "
+ "back on geometry attribute");
attribute = ft.getGeometryDescriptor().getLocalName();
} else {
// Make sure the attribute is actually there
AttributeType attributeType = ft.getType(attribute);
if (attributeType == null) {
throw new ServiceException("Could not find regionating attribute "
+ attribute + " in layer " + featureType.getName());
}
}
// geometry size is a double
h2Type = "DOUBLE";
}
@Override
protected String checkAttribute(FeatureTypeInfo cfg){
String attribute = MapLayerInfo.getRegionateAttribute(cfg);
try{
FeatureType ft = cfg.getFeatureType();
if ((attribute != null) && (ft.getDescriptor(attribute) != null))
return attribute;
return ft.getGeometryDescriptor().getLocalName();
} catch (Exception e) {
LOGGER.severe("Couldn't get attribute name due to " + e);
return null;
}
}
@Override
protected Double getSortAttributeValue(SimpleFeature f) {
Geometry g = (Geometry) f.getAttribute(attribute);
if (g instanceof MultiPoint)
return (double) ((MultiPoint) g).getNumGeometries();
if (g instanceof Polygon || g instanceof MultiPolygon)
return g.getArea();
else
return g.getLength();
}
}