use of org.geotoolkit.display2d.primitive.ProjectedFeature in project geotoolkit by Geomatys.
the class PieSymbolizerRenderer method presentations.
@Override
public Stream<Presentation> presentations(MapLayer layer, Resource resource) {
if (!(resource instanceof FeatureSet)) {
return Stream.empty();
}
final FeatureSet fs = (FeatureSet) resource;
final Expression size = symbol.getSource().getSize();
final Expression group = symbol.getSource().getGroup();
final Expression quarter = symbol.getSource().getQuarter();
final Expression value = symbol.getSource().getValue();
final List<PieSymbolizer.ColorQuarter> colorQuarters = symbol.getSource().getColorQuarters();
if (group == null || quarter == null || value == null) {
return Stream.empty();
}
try (final RenderingRoutines.GraphicIterator ite = RenderingRoutines.getIterator(fs, renderingContext)) {
final Map<Object, PropsPie> vals = new HashMap<>();
while (ite.hasNext()) {
try {
final Object next = ite.next();
final Feature f;
if (next instanceof ProjectedFeature) {
f = ((ProjectedFeature) next).getCandidate();
} else {
continue;
}
final Object key = group.apply(f);
final Object quarterKey = quarter.apply(f);
final double valueKey = ((Number) value.apply(f)).doubleValue();
PropsPie propsPie = vals.get(key);
if (propsPie == null) {
propsPie = new PropsPie();
vals.put(key, propsPie);
}
propsPie.geometries = ((ProjectedFeature) next).getGeometry(null).getDisplayGeometryJTS();
if (size != null) {
final Number s = (Number) size.apply(f);
if (s != null && !Double.isNaN(s.doubleValue()) && s.doubleValue() > 0) {
propsPie.size = s.doubleValue();
}
}
Double oldQuarter = propsPie.vals.get(quarterKey);
if (oldQuarter == null) {
oldQuarter = valueKey;
} else {
oldQuarter += valueKey;
}
propsPie.vals.put(quarterKey, oldQuarter);
} catch (Exception ex) {
ExceptionPresentation ep = new ExceptionPresentation(ex);
ep.setLayer(layer);
ep.setResource(resource);
return Stream.of(ep);
}
}
renderingContext.switchToDisplayCRS();
final Graphics2D g = renderingContext.getGraphics();
for (final PropsPie propsPie : vals.values()) {
final double pieSize = propsPie.size;
double nbTotalValue = 0;
for (final Double val : propsPie.vals.values()) {
if (val != null && !Double.isNaN(val)) {
nbTotalValue += val;
}
}
if (nbTotalValue != 0) {
double startDegree = 0;
double countOthers = 0;
for (final Map.Entry<Object, Double> entryPropsVal : propsPie.vals.entrySet()) {
if (entryPropsVal.getValue() == null || Double.isNaN(entryPropsVal.getValue())) {
continue;
}
double degrees = entryPropsVal.getValue() * 360 / nbTotalValue;
for (final Geometry geom : propsPie.geometries) {
// Try to find the matching color for this quarter of pie
Color c = null;
for (final PieSymbolizer.ColorQuarter candidate : colorQuarters) {
if (entryPropsVal.getKey().equals(candidate.getQuarter().apply(null))) {
c = (Color) candidate.getColor().apply(null);
break;
}
}
if (c == null) {
// Not specified, so go to others group
countOthers += entryPropsVal.getValue();
break;
}
final Point center = geom.getCentroid();
final Arc2D arc = new Arc2D.Double(center.getX() - pieSize / 2, center.getY() - pieSize / 2, pieSize, pieSize, startDegree, degrees, Arc2D.PIE);
g.setPaint(c);
g.fill(arc);
g.setStroke(new BasicStroke(1));
g.setPaint(Color.BLACK);
g.draw(arc);
startDegree += degrees;
}
}
if (countOthers > 0) {
for (final Geometry geom : propsPie.geometries) {
double degrees = countOthers * 360 / nbTotalValue;
final Point center = geom.getCentroid();
final Arc2D arc = new Arc2D.Double(center.getX() - pieSize / 2, center.getY() - pieSize / 2, pieSize, pieSize, startDegree, degrees, Arc2D.PIE);
g.setPaint(Color.GRAY);
g.fill(arc);
g.setStroke(new BasicStroke(1));
g.setPaint(Color.BLACK);
g.draw(arc);
}
}
}
}
return Stream.empty();
} catch (DataStoreException | IOException ex) {
ExceptionPresentation ep = new ExceptionPresentation(ex);
ep.setLayer(layer);
ep.setResource(resource);
return Stream.of(ep);
}
}
use of org.geotoolkit.display2d.primitive.ProjectedFeature in project geotoolkit by Geomatys.
the class CellSymbolizerRenderer method presentations.
private Stream<Presentation> presentations(MapLayer layer, FeatureSet fs) {
// calculate the cells
final int cellSize = symbol.getSource().getCellSize();
final AffineTransform trs = renderingContext.getDisplayToObjective();
final double objCellSize = AffineTransforms2D.getScale(trs) * cellSize;
// find min and max cols/rows
final Envelope env = renderingContext.getCanvasObjectiveBounds2D();
final CoordinateReferenceSystem crs = env.getCoordinateReferenceSystem();
final int minCol = (int) (env.getMinimum(0) / objCellSize);
final int maxCol = (int) ((env.getMaximum(0) / objCellSize) + 0.5);
final int minRow = (int) (env.getMinimum(1) / objCellSize);
final int maxRow = (int) ((env.getMaximum(1) / objCellSize) + 0.5);
final int nbRow = maxRow - minRow;
final int nbCol = maxCol - minCol;
// create all cell contours
final Polygon[][] contours = new Polygon[nbRow][nbCol];
for (int r = 0; r < nbRow; r++) {
for (int c = 0; c < nbCol; c++) {
final double minx = (minCol + c) * objCellSize;
final double maxx = minx + objCellSize;
final double miny = (minRow + r) * objCellSize;
final double maxy = miny + objCellSize;
contours[r][c] = GF.createPolygon(new Coordinate[] { new Coordinate(minx, miny), new Coordinate(minx, maxy), new Coordinate(maxx, maxy), new Coordinate(maxx, miny), new Coordinate(minx, miny) });
JTS.setCRS(contours[r][c], crs);
}
}
FeatureType baseType = null;
FeatureType cellType = null;
String[] numericProperties = null;
Statistics[][][] stats = null;
try (final RenderingRoutines.GraphicIterator graphics = RenderingRoutines.getIterator(fs, renderingContext)) {
while (graphics.hasNext()) {
final ProjectedObject obj = graphics.next();
final ProjectedFeature projFeature = (ProjectedFeature) obj;
if (baseType == null) {
// we expect all features to have the same type
baseType = projFeature.getCandidate().getType();
cellType = CellSymbolizer.buildCellType(baseType, crs);
final List<String> props = new ArrayList<>();
for (PropertyType desc : baseType.getProperties(true)) {
if (desc instanceof AttributeType) {
final AttributeType att = (AttributeType) desc;
final Class binding = att.getValueClass();
if (Number.class.isAssignableFrom(binding) || String.class.isAssignableFrom(binding)) {
props.add(att.getName().toString());
}
}
}
numericProperties = props.toArray(new String[props.size()]);
stats = new Statistics[numericProperties.length][nbRow][nbCol];
for (int i = 0; i < numericProperties.length; i++) {
for (int j = 0; j < nbRow; j++) {
for (int k = 0; k < nbCol; k++) {
stats[i][j][k] = new Statistics("");
}
}
}
}
final ProjectedGeometry pg = projFeature.getGeometry(geomPropertyName);
final Geometry[] geoms = pg.getObjectiveGeometryJTS();
// find in which cell it intersects
int row = -1;
int col = -1;
loop: for (Geometry g : geoms) {
if (g == null)
continue;
for (int r = 0; r < nbRow; r++) {
for (int c = 0; c < nbCol; c++) {
if (contours[r][c].intersects(g)) {
row = r;
col = c;
break loop;
}
}
}
}
// fill stats
if (row != -1) {
final Feature feature = projFeature.getCandidate();
for (int i = 0; i < numericProperties.length; i++) {
final Object value = feature.getProperty(numericProperties[i]).getValue();
try {
final Number num = ObjectConverters.convert(value, Number.class);
if (num != null) {
stats[i][row][col].accept(num.doubleValue());
}
} catch (UnconvertibleObjectException e) {
Logging.recoverableException(LOGGER, CellSymbolizerRenderer.class, "portray", e);
// TODO - do we really want to ignore?
}
}
}
}
} catch (DataStoreException | IOException | TransformException ex) {
ExceptionPresentation ep = new ExceptionPresentation(ex);
ep.setLayer(layer);
ep.setResource(fs);
return Stream.of(ep);
}
if (numericProperties == null) {
// nothing in the iterator
return Stream.empty();
}
// render the cell features
final Object[] values = new Object[2 + 7 * numericProperties.length];
final List<Feature> features = new ArrayList<>();
for (int r = 0; r < nbRow; r++) {
for (int c = 0; c < nbCol; c++) {
final Feature feature = cellType.newInstance();
feature.setPropertyValue(AttributeConvention.IDENTIFIER, "cell-n");
values[0] = contours[r][c].getCentroid();
JTS.setCRS(((Geometry) values[0]), crs);
values[1] = contours[r][c];
int k = 1;
for (int b = 0, n = numericProperties.length; b < n; b++) {
values[++k] = stats[b][r][c].count();
values[++k] = stats[b][r][c].minimum();
values[++k] = stats[b][r][c].mean();
values[++k] = stats[b][r][c].maximum();
values[++k] = stats[b][r][c].span();
values[++k] = stats[b][r][c].rms();
values[++k] = stats[b][r][c].sum();
}
features.add(feature);
}
}
final Rule rule = symbol.getSource().getRule();
final InMemoryFeatureSet subfs = new InMemoryFeatureSet(cellType, features);
final MapLayer subLayer = MapBuilder.createLayer(subfs);
subLayer.setStyle(GO2Utilities.STYLE_FACTORY.style(rule.symbolizers().toArray(new Symbolizer[0])));
return DefaultPortrayalService.present(subLayer, subfs, renderingContext);
}
use of org.geotoolkit.display2d.primitive.ProjectedFeature in project geotoolkit by Geomatys.
the class PointSymbolizerRenderer method presentations.
@Override
public Stream<Presentation> presentations(MapLayer layer, Feature feature) {
final ProjectedFeature pf = new ProjectedFeature(renderingContext, feature);
final Feature candidate = pf.getCandidate();
// test if the symbol is visible on this feature
if (symbol.isVisible(candidate)) {
final ProjectedGeometry projectedGeometry = pf.getGeometry(geomPropertyName);
final DefaultGroupPresentation group = new DefaultGroupPresentation(layer, layer.getData(), candidate);
try {
if (presentation(group, projectedGeometry, candidate)) {
return Stream.of(group);
}
} catch (TransformException ex) {
ExceptionPresentation ep = new ExceptionPresentation(ex);
ep.setLayer(layer);
ep.setResource(layer.getData());
ep.setCandidate(feature);
return Stream.of(ep);
}
}
return Stream.empty();
}
use of org.geotoolkit.display2d.primitive.ProjectedFeature in project geotoolkit by Geomatys.
the class RenderingRoutines method getIterator.
public static GraphicIterator getIterator(final FeatureSet features, final RenderingContext2D renderingContext) throws DataStoreException {
final FeatureIterator iterator;
final Stream<Feature> stream = features.features(false);
final Iterator<Feature> i = stream.iterator();
iterator = new FeatureIterator() {
@Override
public Feature next() throws FeatureStoreRuntimeException {
return i.next();
}
@Override
public boolean hasNext() throws FeatureStoreRuntimeException {
return i.hasNext();
}
@Override
public void close() {
stream.close();
}
};
final ProjectedFeature projectedFeature = new ProjectedFeature(renderingContext);
return new GraphicIterator(iterator, projectedFeature);
}
Aggregations