@Override public void run() { while (true) { synchronized (lastestPosition) { currentPosition.set(lastestPosition); } // obtain the coordiante in geographic crs final ReadOnlyVector3 corrected = container.correctLocation(currentPosition); for (Double key : sensitives.keySet()) { final Object[] combination = sensitives.get(key); final Vector3 vect = (Vector3) combination[0]; final List<LocationSensitiveGraphic> graphics = (List<LocationSensitiveGraphic>) combination[1]; if (vect.distance(currentPosition) > key) { vect.set(currentPosition); for (LocationSensitiveGraphic gra : graphics) { gra.update(corrected); } } } try { // we dont need to consume much cpu sleep(100); } catch (InterruptedException ex) { Logging.getLogger(LocationSensitiveUpdater.class).log(Level.WARNING, null, ex); } } }
/** * setUp Called before each test. * * @throws FactoryException */ static { CRSFactory crsFact = AuthorityFactoryFinder.getCRSFactory(null); try { crs = crsFact.createFromWKT(WGS84_WKT); } catch (FactoryException ex) { Logging.getLogger(AbstractGeometryTest.class).log(Level.WARNING, null, ex); } GEOMETRY_FACTORY = new JTSGeometryFactory(crs); PRIMITIVE_FACTORY = new JTSPrimitiveFactory(crs); }
/** * Informations relative to a rendering in progress. A {@code RenderingContext} instance is created * by {@link J2DCanvas} at rendering time, which iterates over all graphic objects and invokes the * rendering process for each of them. The rendering context is disposed once the rendering is * completed. {@code RenderingContext} instances contain the following informations: * * <p> * * <ul> * <li>The {@link Graphics2D} handler to use for rendering. * <li>The coordinate reference systems in use and the transformations between them. * <li>The area rendered up to date. This information shall be updated by each {@link GraphicJ2D} * while they are painting. * <li>The map scale. * </ul> * * <p>A rendering usually implies the following transformations (names are {@linkplain * CoordinateReferenceSystem coordinate reference systems} and arrows are {@linkplain MathTransform * transforms}): * * <p align="center"> {@code graphicCRS} <img src="doc-files/right.png"> {@link * #objectiveCRS} <img src="doc-files/right.png"> {@link #displayCRS} <img * src="doc-files/right.png"> {@code deviceCRS} * * @module pending * @since 2.3 * @version $Id$ * @author Martin Desruisseaux (IRD) * @author Johann Sorel (Geomatys) */ public final class DefaultRenderingContext2D implements RenderingContext2D { private static final Logger LOGGER = Logging.getLogger(DefaultRenderingContext2D.class); private static Map<Font, FontMetrics> fontMetrics = new HashMap<Font, FontMetrics>(); private static final int DISPLAY_TRS = 0; private static final int OBJECTIVE_TRS = 1; private static final int OTHER_TRS = 2; private int current = DISPLAY_TRS; /** The originating canvas. */ private final J2DCanvas canvas; /** * The graphics handle to use for painting. This graphics is set by {@link BufferedCanvas2D} when * a new painting in underway. It is reset to {@code null} once the rendering is finished. * * @see #getGraphics */ private Graphics2D graphics = null; /* * cache of the Graphics2D rendering hints. */ private RenderingHints renderingHints = null; private double dpi = 90; /** * A snapshot of {@link ReferencedCanvas#getObjectiveCRS} at the time of painting. This is the * "real world" coordinate reference system that the user will see on the screen. Data from all * {@link GraphicPrimitive2D} must be transformed to this CRS before to be painted. Units are * usually "real world" metres. * * <p>This coordinate system is usually set once for a given {@link BufferedCanvas2D} and do not * change anymore, except if the user wants to change the projection see on screen. * * @see #displayCRS * @see #setGraphicsCRS * @see ReferencedCanvas#getObjectiveCRS */ private CoordinateReferenceSystem objectiveCRS = null; private CoordinateReferenceSystem objectiveCRS2D = null; /** * A snapshot of {@link ReferencedCanvas#getDisplayCRS} at the time of painting. This CRS maps the * {@linkplain Graphics2D user space} in terms of <cite>Java2D</cite>: each "unit" is a dot (about * 1/72 of inch). <var>x</var> values increase toward the right of the screen and <var>y</var> * values increase toward the bottom of the screen. This CRS is appropriate for rendering text and * labels. * * <p>This coordinate system may be different between two different renderings, especially if the * zoom (or map scale) has changed since the last rendering. * * @see #objectiveCRS * @see #setGraphicsCRS * @see ReferencedCanvas#getDisplayCRS */ private CoordinateReferenceSystem displayCRS = null; private CanvasMonitor monitor = null; private AffineTransform2D objectiveToDisplay = null; private AffineTransform2D displayToObjective = null; /** * The affine transform from {@link #objectiveCRS} to {@code deviceCRS}. Used by {@link * #setGraphicsCRS} when the CRS is {@link #objectiveCRS}. This is a pretty common case, and * unfortunatly one that is badly optimized by {@link ReferencedCanvas#getMathTransform}. */ private AffineTransform objectiveToDevice = null; /** * The affine transform from {@link #displayCRS} to {@code deviceCRS}. Used by {@link * #setGraphicsCRS} when the CRS is {@link #displayCRS}. */ private AffineTransform displayToDevice = null; /** The label renderer. Shall be created only once. */ private LabelRenderer labelRenderer = null; /** List of coefficients from "Unit" to Objective CRS. */ private final Map<Unit<Length>, Float> coeffs = new IdentityHashMap<Unit<Length>, Float>(); /** Precalculated resolution, avoid graphics to recalculate it since */ private double[] resolution; /** Precalculated geographic scale, avoid graphics to recalculate it. */ private double geoScale = 1; /** * Precaculated geographic scale calculated using OGC Symbology Encoding Specification. This is * not the scale Objective to Display. This is not an accurate geographic scale. This is a fake * average scale unproper for correct rendering. It is used only to filter SE rules. */ private double seScale = 1; private final Date[] temporalRange = new Date[2]; private final Double[] elevationRange = new Double[2]; private Shape paintingDisplayShape = null; private Rectangle paintingDisplaybounds = null; private Shape paintingObjectiveShape = null; private Envelope paintingObjectiveBBox = null; private Envelope paintingObjectiveBBox2D = null; private Shape canvasDisplayShape = null; private Rectangle canvasDisplaybounds = null; private Shape canvasObjectiveShape = null; private Envelope canvasObjectiveBBox = null; private Envelope canvasObjectiveBBox2D = null; /** * Constructs a new {@code RenderingContext} for the specified canvas. * * @param canvas The canvas which creates this rendering context. */ public DefaultRenderingContext2D(final J2DCanvas canvas) { this.canvas = canvas; } public void initParameters( final AffineTransform2D objToDisp, final CanvasMonitor monitor, final Shape paintingDisplayShape, final Shape paintingObjectiveShape, final Shape canvasDisplayShape, final Shape canvasObjectiveShape, final double dpi) { this.canvasObjectiveBBox = canvas.getController().getVisibleEnvelope(); this.objectiveCRS = canvasObjectiveBBox.getCoordinateReferenceSystem(); this.objectiveCRS2D = canvas.getObjectiveCRS2D(); this.displayCRS = canvas.getDisplayCRS(); this.objectiveToDisplay = objToDisp; try { this.displayToObjective = (AffineTransform2D) objToDisp.inverse(); } catch (NoninvertibleTransformException ex) { Logging.getLogger(DefaultRenderingContext2D.class).log(Level.WARNING, null, ex); } this.monitor = monitor; this.labelRenderer = null; this.coeffs.clear(); // set the Pixel coeff = 1 this.coeffs.put(NonSI.PIXEL, 1f); // calculate canvas shape/bounds values --------------------------------- this.canvasDisplayShape = canvasDisplayShape; final Rectangle2D canvasDisplayBounds = canvasDisplayShape.getBounds2D(); this.canvasDisplaybounds = canvasDisplayBounds.getBounds(); this.canvasObjectiveShape = canvasObjectiveShape; final Rectangle2D canvasObjectiveBounds = canvasObjectiveShape.getBounds2D(); // calculate the objective bbox with there temporal and elevation parameters ---- this.canvasObjectiveBBox2D = new Envelope2D(objectiveCRS2D, canvasObjectiveBounds); // calculate the resolution ----------------------------------------------- this.dpi = dpi; this.resolution = new double[canvasObjectiveBBox.getDimension()]; this.resolution[0] = canvasObjectiveBounds.getWidth() / canvasDisplayBounds.getWidth(); this.resolution[1] = canvasObjectiveBounds.getHeight() / canvasDisplayBounds.getHeight(); for (int i = 2; i < resolution.length; i++) { // other dimension are likely to be the temporal and elevation one. // we set a hug resolution to ensure that only one slice of data will be retrived. resolution[i] = Double.MAX_VALUE; } adjustResolutionWithDPI(resolution); // calculate painting shape/bounds values ------------------------------- this.paintingDisplayShape = paintingDisplayShape; final Rectangle2D paintingDisplayBounds = paintingDisplayShape.getBounds2D(); this.paintingDisplaybounds = paintingDisplayBounds.getBounds(); this.paintingObjectiveShape = paintingObjectiveShape; final Rectangle2D paintingObjectiveBounds = paintingObjectiveShape.getBounds2D(); this.paintingObjectiveBBox2D = new Envelope2D(objectiveCRS2D, paintingObjectiveBounds); this.paintingObjectiveBBox = new GeneralEnvelope(canvasObjectiveBBox); ((GeneralEnvelope) this.paintingObjectiveBBox) .setRange(0, paintingObjectiveBounds.getMinX(), paintingObjectiveBounds.getMaxX()); ((GeneralEnvelope) this.paintingObjectiveBBox) .setRange(1, paintingObjectiveBounds.getMinY(), paintingObjectiveBounds.getMaxY()); try { geoScale = canvas.getController().getGeographicScale(); } catch (TransformException ex) { // could not calculate the geographic scale. geoScale = 1; LOGGER.log(Level.WARNING, null, ex); } // set temporal and elevation range-------------------------------------- final Date[] temporal = canvas.getController().getTemporalRange(); if (temporal != null) { temporalRange[0] = temporal[0]; temporalRange[1] = temporal[1]; } else { Arrays.fill(temporalRange, null); } final Double[] elevation = canvas.getController().getElevationRange(); if (elevation != null) { elevationRange[0] = elevation[0]; elevationRange[1] = elevation[1]; } else { Arrays.fill(elevationRange, null); } // calculate the symbology encoding scale ------------------------------- seScale = GO2Utilities.computeSEScale(this); } public void initGraphic(final Graphics2D graphics) { this.graphics = graphics; this.renderingHints = graphics.getRenderingHints(); this.displayToDevice = (graphics != null) ? graphics.getTransform() : null; this.objectiveToDevice = (displayToDevice != null) ? new AffineTransform(displayToDevice) : new AffineTransform(); this.objectiveToDevice.concatenate(objectiveToDisplay); this.current = DISPLAY_TRS; } public void reset() { this.coeffs.clear(); this.canvasDisplaybounds = null; this.displayCRS = null; this.canvasDisplayShape = null; this.displayToDevice = null; this.graphics = null; this.renderingHints = null; this.labelRenderer = null; this.monitor = null; this.canvasObjectiveBBox = null; this.objectiveCRS = null; this.canvasObjectiveShape = null; this.objectiveToDevice = null; this.objectiveToDisplay = null; this.resolution = null; this.current = DISPLAY_TRS; } public void dispose() { if (graphics != null) { graphics.dispose(); } reset(); } /** {@inheritDoc } */ @Override public J2DCanvas getCanvas() { return canvas; } /** {@inheritDoc } */ @Override public CoordinateReferenceSystem getObjectiveCRS() { return objectiveCRS; } /** {@inheritDoc } */ @Override public CoordinateReferenceSystem getObjectiveCRS2D() { return objectiveCRS2D; } /** {@inheritDoc } */ @Override public CoordinateReferenceSystem getDisplayCRS() { return displayCRS; } /** {@inheritDoc } */ @Override public final Graphics2D getGraphics() { return graphics; } /** {@inheritDoc } */ @Override public void switchToDisplayCRS() { if (current != DISPLAY_TRS) { graphics.setTransform(displayToDevice); current = DISPLAY_TRS; } } /** {@inheritDoc } */ @Override public void switchToObjectiveCRS() { if (current != OBJECTIVE_TRS) { graphics.setTransform(objectiveToDevice); current = OBJECTIVE_TRS; } } /** {@inheritDoc } */ @Override public void setGraphicsCRS(CoordinateReferenceSystem crs) throws TransformException { if (crs == displayCRS) { switchToDisplayCRS(); } else if (crs == objectiveCRS || crs == objectiveCRS2D) { switchToObjectiveCRS(); } else try { crs = CRSUtilities.getCRS2D(crs); AffineTransform at = getAffineTransform(crs, displayCRS); at.preConcatenate(displayToDevice); current = OTHER_TRS; graphics.setTransform(at); } catch (FactoryException e) { throw new TransformException( Errors.format(Errors.Keys.ILLEGAL_COORDINATE_REFERENCE_SYSTEM), e); } } /** {@inheritDoc } */ @Override public AffineTransform getAffineTransform( final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS) throws FactoryException { final MathTransform mt = canvas.getMathTransform( sourceCRS, targetCRS, DefaultRenderingContext2D.class, "getAffineTransform"); try { return (AffineTransform) mt; } catch (ClassCastException cause) { throw new FactoryException(Errors.format(Errors.Keys.NOT_AN_AFFINE_TRANSFORM), cause); } } /** {@inheritDoc } */ @Override public MathTransform getMathTransform( final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS) throws FactoryException { return canvas.getMathTransform( sourceCRS, targetCRS, DefaultRenderingContext2D.class, "getMathTransform"); } /** {@inheritDoc } */ @Override public RenderingContext2D create(final Graphics2D g2d) { final DefaultRenderingContext2D context = new DefaultRenderingContext2D(canvas); context.initParameters( objectiveToDisplay, monitor, paintingDisplayShape, paintingObjectiveShape, canvasDisplayShape, canvasObjectiveShape, dpi); context.initGraphic(g2d); g2d.setRenderingHints(this.graphics.getRenderingHints()); context.labelRenderer = getLabelRenderer(true); return context; } /** {@inheritDoc } */ @Override public LabelRenderer getLabelRenderer(final boolean create) { if (labelRenderer == null && create) { Class candidate = (Class) canvas.getRenderingHint(GO2Hints.KEY_LABEL_RENDERER_CLASS); if (candidate != null && LabelRenderer.class.isAssignableFrom(candidate)) { try { labelRenderer = (LabelRenderer) candidate.newInstance(); labelRenderer.setRenderingContext(this); } catch (InstantiationException ex) { LOGGER.log(Level.WARNING, null, ex); } catch (IllegalAccessException ex) { LOGGER.log(Level.WARNING, null, ex); } } else { labelRenderer = new DecimationLabelRenderer(); labelRenderer.setRenderingContext(this); } } return labelRenderer; } /** {@inheritDoc } */ @Override public CanvasMonitor getMonitor() { return monitor; } // Informations related to scale datas ------------------------------------- /** {@inheritDoc } */ @Override public float getUnitCoefficient(final Unit<Length> uom) { Float f = coeffs.get(uom); if (f == null) { f = GO2Utilities.calculateScaleCoefficient(this, uom); coeffs.put(uom, f); } return f; } public double getDPI() { return dpi; } /** {@inheritDoc } */ @Override public double[] getResolution() { return resolution.clone(); } /** {@inheritDoc } */ @Override public double[] getResolution(final CoordinateReferenceSystem crs) { if (CRS.equalsIgnoreMetadata(objectiveCRS, crs)) { return getResolution(); } else { final double[] res = new double[crs.getCoordinateSystem().getDimension()]; final Envelope env; try { env = CRS.transform(canvasObjectiveBBox2D, crs); final Rectangle2D canvasCRSBounds = new Rectangle2D.Double(0, 0, env.getSpan(0), env.getSpan(1)); res[0] = Math.abs(canvasCRSBounds.getWidth() / canvasDisplaybounds.getWidth()); res[1] = Math.abs(canvasCRSBounds.getHeight() / canvasDisplaybounds.getHeight()); for (int i = 2; i < res.length; i++) { // other dimension are likely to be the temporal and elevation one. // we set a hug resolution to ensure that only one slice of data will be retrived. res[i] = Double.MAX_VALUE; } } catch (TransformException ex) { LOGGER.log(Level.WARNING, null, ex); } catch (IllegalArgumentException ex) { LOGGER.log(Level.WARNING, null, ex); } catch (Exception ex) { LOGGER.log(Level.WARNING, null, ex); } return adjustResolutionWithDPI(res); } } /** * Adjust the resolution relative to 90 DPI. a dpi under 90 with raise the resolution level while * a bigger spi will lower the resolution level. */ private double[] adjustResolutionWithDPI(final double[] res) { res[0] = (90 / dpi) * res[0]; res[1] = (90 / dpi) * res[1]; return res; } /** {@inheritDoc } */ @Override public double getScale() { return canvas.getController().getScale(); } /** {@inheritDoc } */ @Override public double getGeographicScale() { return geoScale; } /** {@inheritDoc } */ @Override public double getSEScale() { return seScale; } // Informations about the currently painted area --------------------------- /** {@inheritDoc } */ @Override public Shape getPaintingDisplayShape() { return paintingDisplayShape; } /** {@inheritDoc } */ @Override public Rectangle getPaintingDisplayBounds() { return paintingDisplaybounds; } /** {@inheritDoc } */ @Override public Shape getPaintingObjectiveShape() { return paintingObjectiveShape; } /** {@inheritDoc } */ @Override public BoundingBox getPaintingObjectiveBounds2D() { return new DefaultBoundingBox(paintingObjectiveBBox2D); } /** {@inheritDoc } */ @Override public Envelope getPaintingObjectiveBounds() { return paintingObjectiveBBox; } // Informations about the complete canvas area ----------------------------- /** {@inheritDoc } */ @Override public Shape getCanvasDisplayShape() { return canvasDisplayShape; } /** {@inheritDoc } */ @Override public Rectangle getCanvasDisplayBounds() { return canvasDisplaybounds; } /** {@inheritDoc } */ @Override public Shape getCanvasObjectiveShape() { return canvasObjectiveShape; } /** {@inheritDoc } */ @Override public BoundingBox getCanvasObjectiveBounds2D() { return new DefaultBoundingBox(canvasObjectiveBBox2D); } /** {@inheritDoc } */ @Override public Envelope getCanvasObjectiveBounds() { return canvasObjectiveBBox; } @Override public AffineTransform2D getObjectiveToDisplay() { return objectiveToDisplay; } @Override public AffineTransform2D getDisplayToObjective() { return displayToObjective; } @Override public Date[] getTemporalRange() { return temporalRange; } @Override public Double[] getElevationRange() { return elevationRange; } @Override public RenderingHints getRenderingHints() { return renderingHints; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("========== Rendering Context 2D ==========\n"); sb.append("---------- Coordinate Reference Systems ----------\n"); sb.append("Objective CRS = \n"); sb.append(objectiveCRS).append("\n"); sb.append("Objective CRS 2D = \n"); sb.append(objectiveCRS2D).append("\n"); sb.append("Display CRS = \n"); sb.append(displayCRS).append("\n"); if (resolution != null) { sb.append("Resolution = "); for (double d : resolution) { sb.append(d).append(" "); } } sb.append("\n"); sb.append("Geographic Scale = "); sb.append(geoScale).append("\n"); sb.append("OGC SE Scale = "); sb.append(seScale).append("\n"); sb.append("Temporal range = "); sb.append(temporalRange[0]).append(" to ").append(temporalRange[1]).append("\n"); sb.append("Elevation range = "); sb.append(elevationRange[0]).append(" to ").append(elevationRange[1]).append("\n"); sb.append("\n---------- Canvas Geometries ----------\n"); sb.append("Display Shape = \n"); sb.append(canvasDisplayShape).append("\n"); sb.append("Display Bounds = \n"); sb.append(canvasDisplaybounds).append("\n"); sb.append("Objective Shape = \n"); sb.append(canvasObjectiveShape).append("\n"); sb.append("Objective BBOX = \n"); sb.append(canvasObjectiveBBox).append("\n"); sb.append("Objective BBOX 2D = \n"); sb.append(canvasObjectiveBBox2D).append("\n"); sb.append("\n---------- Painting Geometries (dirty area) ----------\n"); sb.append("Display Shape = \n"); sb.append(paintingDisplayShape).append("\n"); sb.append("Display Bounds = \n"); sb.append(paintingDisplaybounds).append("\n"); sb.append("Objective Shape = \n"); sb.append(paintingObjectiveShape).append("\n"); sb.append("Objective BBOX = \n"); sb.append(paintingObjectiveBBox).append("\n"); sb.append("Objective BBOX 2D = \n"); sb.append(paintingObjectiveBBox2D).append("\n"); sb.append("\n---------- Transforms ----------\n"); sb.append("Objective to Display = \n"); sb.append(objectiveToDisplay).append("\n"); sb.append("Display to Objective = \n"); sb.append(displayToObjective).append("\n"); sb.append("\n---------- Rendering Hints ----------\n"); if (renderingHints != null) { for (Entry<Object, Object> entry : renderingHints.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()).append("\n"); } } sb.append("========== Rendering Context 2D ==========\n"); return sb.toString(); } @Override public FontMetrics getFontMetrics(Font f) { FontMetrics fm = fontMetrics.get(f); if (fm == null) { fm = getGraphics().getFontMetrics(f); fontMetrics.put(f, fm); } return fm; } }
public void initParameters( final AffineTransform2D objToDisp, final CanvasMonitor monitor, final Shape paintingDisplayShape, final Shape paintingObjectiveShape, final Shape canvasDisplayShape, final Shape canvasObjectiveShape, final double dpi) { this.canvasObjectiveBBox = canvas.getController().getVisibleEnvelope(); this.objectiveCRS = canvasObjectiveBBox.getCoordinateReferenceSystem(); this.objectiveCRS2D = canvas.getObjectiveCRS2D(); this.displayCRS = canvas.getDisplayCRS(); this.objectiveToDisplay = objToDisp; try { this.displayToObjective = (AffineTransform2D) objToDisp.inverse(); } catch (NoninvertibleTransformException ex) { Logging.getLogger(DefaultRenderingContext2D.class).log(Level.WARNING, null, ex); } this.monitor = monitor; this.labelRenderer = null; this.coeffs.clear(); // set the Pixel coeff = 1 this.coeffs.put(NonSI.PIXEL, 1f); // calculate canvas shape/bounds values --------------------------------- this.canvasDisplayShape = canvasDisplayShape; final Rectangle2D canvasDisplayBounds = canvasDisplayShape.getBounds2D(); this.canvasDisplaybounds = canvasDisplayBounds.getBounds(); this.canvasObjectiveShape = canvasObjectiveShape; final Rectangle2D canvasObjectiveBounds = canvasObjectiveShape.getBounds2D(); // calculate the objective bbox with there temporal and elevation parameters ---- this.canvasObjectiveBBox2D = new Envelope2D(objectiveCRS2D, canvasObjectiveBounds); // calculate the resolution ----------------------------------------------- this.dpi = dpi; this.resolution = new double[canvasObjectiveBBox.getDimension()]; this.resolution[0] = canvasObjectiveBounds.getWidth() / canvasDisplayBounds.getWidth(); this.resolution[1] = canvasObjectiveBounds.getHeight() / canvasDisplayBounds.getHeight(); for (int i = 2; i < resolution.length; i++) { // other dimension are likely to be the temporal and elevation one. // we set a hug resolution to ensure that only one slice of data will be retrived. resolution[i] = Double.MAX_VALUE; } adjustResolutionWithDPI(resolution); // calculate painting shape/bounds values ------------------------------- this.paintingDisplayShape = paintingDisplayShape; final Rectangle2D paintingDisplayBounds = paintingDisplayShape.getBounds2D(); this.paintingDisplaybounds = paintingDisplayBounds.getBounds(); this.paintingObjectiveShape = paintingObjectiveShape; final Rectangle2D paintingObjectiveBounds = paintingObjectiveShape.getBounds2D(); this.paintingObjectiveBBox2D = new Envelope2D(objectiveCRS2D, paintingObjectiveBounds); this.paintingObjectiveBBox = new GeneralEnvelope(canvasObjectiveBBox); ((GeneralEnvelope) this.paintingObjectiveBBox) .setRange(0, paintingObjectiveBounds.getMinX(), paintingObjectiveBounds.getMaxX()); ((GeneralEnvelope) this.paintingObjectiveBBox) .setRange(1, paintingObjectiveBounds.getMinY(), paintingObjectiveBounds.getMaxY()); try { geoScale = canvas.getController().getGeographicScale(); } catch (TransformException ex) { // could not calculate the geographic scale. geoScale = 1; LOGGER.log(Level.WARNING, null, ex); } // set temporal and elevation range-------------------------------------- final Date[] temporal = canvas.getController().getTemporalRange(); if (temporal != null) { temporalRange[0] = temporal[0]; temporalRange[1] = temporal[1]; } else { Arrays.fill(temporalRange, null); } final Double[] elevation = canvas.getController().getElevationRange(); if (elevation != null) { elevationRange[0] = elevation[0]; elevationRange[1] = elevation[1]; } else { Arrays.fill(elevationRange, null); } // calculate the symbology encoding scale ------------------------------- seScale = GO2Utilities.computeSEScale(this); }
/** @author Guilhem Legal (Geomatys) */ public class ElementFeatureWriter { /** Logger for this writer. */ protected static final Logger LOGGER = Logging.getLogger(JAXPStreamFeatureWriter.class); /** The pool of marshallers used for marshalling geometries. */ private static final MarshallerPool POOL = JTSWrapperMarshallerPool.getInstance(); /** Object factory to build a geometry. */ private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory(); protected String schemaLocation; private int lastUnknowPrefix = 0; private final Map<String, String> unknowNamespaces = new HashMap<String, String>(); public ElementFeatureWriter() {} public ElementFeatureWriter(final Map<String, String> schemaLocations) { if (schemaLocations != null && schemaLocations.size() > 0) { final StringBuilder sb = new StringBuilder(); for (Entry<String, String> entry : schemaLocations.entrySet()) { sb.append(entry.getKey()).append(' ').append(entry.getValue()).append(' '); } if (sb.length() > 0) { sb.setLength(sb.length() - 1); // remove last ' ' } schemaLocation = sb.toString(); } } /** {@inheritDoc} */ public Element write(final Object candidate, final boolean fragment) throws IOException, DataStoreException, ParserConfigurationException { if (candidate instanceof Feature) { return writeFeature((Feature) candidate, null, fragment); } else if (candidate instanceof FeatureCollection) { return writeFeatureCollection((FeatureCollection) candidate, fragment, true); } else { throw new IllegalArgumentException( "The given object is not a Feature or a" + " FeatureCollection: " + candidate); } } /** * Write the feature into the stream. * * @param feature The feature * @param root * @throws XMLStreamException */ public Element writeFeature(final Feature feature, final Document rootDocument, boolean fragment) throws ParserConfigurationException { final Document document; if (rootDocument == null) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // then we have to create document-loader: factory.setNamespaceAware(false); DocumentBuilder loader = factory.newDocumentBuilder(); // creating a new DOM-document... document = loader.newDocument(); } else { document = rootDocument; } // the root element of the xml document (type of the feature) final FeatureType type = feature.getType(); final Name typeName = type.getName(); final String namespace = typeName.getNamespaceURI(); final String localPart = typeName.getLocalPart(); final Element rootElement; final Prefix prefix; if (namespace != null) { prefix = getPrefix(namespace); rootElement = document.createElementNS(namespace, localPart); rootElement.setPrefix(prefix.prefix); } else { rootElement = document.createElement(localPart); prefix = null; } // if main document set the xmlns if (!fragment) { rootElement.setAttributeNS( "http://www.w3.org/2000/xmlns/", "xmlns:gml", "http://www.opengis.net/gml"); } final Attr idAttr = document.createAttributeNS(Namespaces.GML, "id"); idAttr.setValue(feature.getIdentifier().getID()); idAttr.setPrefix("gml"); rootElement.setAttributeNodeNS(idAttr); if (rootDocument == null) { document.appendChild(rootElement); } // write properties in the type order for (final PropertyDescriptor desc : type.getDescriptors()) { final Collection<Property> props = feature.getProperties(desc.getName()); for (Property a : props) { final Object valueA = a.getValue(); final PropertyType typeA = a.getType(); final Name nameA = a.getName(); final String nameProperty = nameA.getLocalPart(); String namespaceProperty = nameA.getNamespaceURI(); if (valueA instanceof Collection && !(typeA instanceof GeometryType)) { for (Object value : (Collection) valueA) { final Element element; if (namespaceProperty != null) { element = document.createElementNS(namespaceProperty, nameProperty); } else { element = document.createElement(nameProperty); } element.setTextContent(Utils.getStringValue(value)); if (prefix != null) { element.setPrefix(prefix.prefix); } rootElement.appendChild(element); } } else if (valueA instanceof Map && !(typeA instanceof GeometryType)) { final Map<?, ?> map = (Map) valueA; for (Entry<?, ?> entry : map.entrySet()) { final Element element; if (namespaceProperty != null) { element = document.createElementNS(namespaceProperty, nameProperty); } else { element = document.createElement(nameProperty); } final Object key = entry.getKey(); if (key != null) { element.setAttribute("name", (String) key); } element.setTextContent(Utils.getStringValue(entry.getValue())); if (prefix != null) { element.setPrefix(prefix.prefix); } rootElement.appendChild(element); } } else if (!(typeA instanceof GeometryType)) { String value = Utils.getStringValue(valueA); if (value != null || (value == null && !a.isNillable())) { if ((nameProperty.equals("name") || nameProperty.equals("description")) && !Namespaces.GML.equals(namespaceProperty)) { namespaceProperty = Namespaces.GML; LOGGER.warning( "the property name and description of a feature must have the GML namespace"); } final Element element; if (namespaceProperty != null) { element = document.createElementNS(namespaceProperty, nameProperty); } else { element = document.createElement(nameProperty); } if (value != null) { element.setTextContent(value); } if (prefix != null) { element.setPrefix(prefix.prefix); } rootElement.appendChild(element); } // we add the geometry } else { if (valueA != null) { final Element element; if (namespaceProperty != null) { element = document.createElementNS(namespaceProperty, nameProperty); } else { element = document.createElement(nameProperty); } if (prefix != null) { element.setPrefix(prefix.prefix); } Geometry isoGeometry = JTSUtils.toISO( (com.vividsolutions.jts.geom.Geometry) valueA, type.getCoordinateReferenceSystem()); Marshaller marshaller = null; try { marshaller = POOL.acquireMarshaller(); marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); marshaller.marshal(OBJECT_FACTORY.buildAnyGeometry(isoGeometry), element); } catch (JAXBException ex) { LOGGER.log( Level.WARNING, "JAXB Exception while marshalling the iso geometry: " + ex.getMessage(), ex); } finally { if (marshaller != null) { POOL.release(marshaller); } } rootElement.appendChild(element); } } } } // writer.writeEndElement(); return rootElement; } /** * @param featureCollection * @param writer * @param fragment : true if we write in a stream, dont write start and end elements * @throws DataStoreException */ public Element writeFeatureCollection( final FeatureCollection featureCollection, final boolean fragment, final boolean wfs) throws DataStoreException, ParserConfigurationException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // then we have to create document-loader: factory.setNamespaceAware(false); DocumentBuilder loader = factory.newDocumentBuilder(); // creating a new DOM-document... Document document = loader.newDocument(); // the XML header if (!fragment) { document.setXmlVersion("1.0"); // writer.writeStartDocument("UTF-8", "1.0"); } // the root Element final Element rootElement; if (wfs) { rootElement = document.createElementNS("http://www.opengis.net/wfs", "FeatureCollection"); rootElement.setPrefix("wfs"); } else { rootElement = document.createElementNS("http://www.opengis.net/gml", "FeatureCollection"); rootElement.setPrefix("gml"); } document.appendChild(rootElement); String collectionID = ""; if (featureCollection.getID() != null) { collectionID = featureCollection.getID(); } final Attr idAttribute = document.createAttributeNS(Namespaces.GML, "id"); idAttribute.setValue(collectionID); idAttribute.setPrefix("gml"); rootElement.setAttributeNodeNS(idAttribute); if (schemaLocation != null && !schemaLocation.equals("")) { rootElement.setAttributeNS( "http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", schemaLocation); } /*FeatureType type = featureCollection.getFeatureType(); if (type != null && type.getName() != null) { String namespace = type.getName().getNamespaceURI(); if (namespace != null && !namespace.equals(Namespaces.GML)) { Prefix prefix = getPrefix(namespace); writer.writeNamespace(prefix.prefix, namespace); } }*/ /* * The boundedby part */ final Element boundElement = writeBounds(featureCollection.getEnvelope(), document); if (boundElement != null) { rootElement.appendChild(boundElement); } // we write each feature member of the collection FeatureIterator iterator = featureCollection.iterator(); try { while (iterator.hasNext()) { final Feature f = iterator.next(); final Element memberElement = document.createElementNS(Namespaces.GML, "featureMember"); memberElement.setPrefix("gml"); memberElement.appendChild(writeFeature(f, document, true)); rootElement.appendChild(memberElement); } } finally { // we close the stream iterator.close(); } return rootElement; } private Element writeBounds(final Envelope bounds, final Document document) { if (bounds != null) { String srsName = null; if (bounds.getCoordinateReferenceSystem() != null) { try { srsName = IdentifiedObjects.lookupIdentifier( Citations.URN_OGC, bounds.getCoordinateReferenceSystem(), true); } catch (FactoryException ex) { LOGGER.log(Level.WARNING, null, ex); } } final Element boundElement = document.createElementNS(Namespaces.GML, "boundedBy"); boundElement.setPrefix("gml"); final Element envElement = document.createElementNS(Namespaces.GML, "Envelope"); envElement.setPrefix("gml"); if (srsName != null) { envElement.setAttribute("srsName", srsName); } else { envElement.setAttribute("srsName", ""); } // lower corner final Element lower = document.createElementNS(Namespaces.GML, "lowerCorner"); String lowValue = bounds.getLowerCorner().getOrdinate(0) + " " + bounds.getLowerCorner().getOrdinate(1); lower.setTextContent(lowValue); lower.setPrefix("gml"); envElement.appendChild(lower); // upper corner final Element upper = document.createElementNS(Namespaces.GML, "upperCorner"); String uppValue = bounds.getUpperCorner().getOrdinate(0) + " " + bounds.getUpperCorner().getOrdinate(1); upper.setTextContent(uppValue); upper.setPrefix("gml"); envElement.appendChild(upper); boundElement.appendChild(envElement); return boundElement; } return null; } /** * Returns the prefix for the given namespace. * * @param namespace The namespace for which we want the prefix. */ private Prefix getPrefix(final String namespace) { String prefix = Namespaces.getPreferredPrefix(namespace, null); boolean unknow = false; if (prefix == null) { prefix = unknowNamespaces.get(namespace); if (prefix == null) { prefix = "ns" + lastUnknowPrefix; lastUnknowPrefix++; unknow = true; unknowNamespaces.put(namespace, prefix); } } return new Prefix(unknow, prefix); } /** Inner class for handling prefix and if it is already known. */ private final class Prefix { public boolean unknow; public String prefix; public Prefix(final boolean unknow, final String prefix) { this.prefix = prefix; this.unknow = unknow; } } }
/** * @author Johann Sorel (Puzzle-GIS) * @module pending */ public class A3DCanvas extends ReferencedCanvas { private static final Logger LOGGER = Logging.getLogger(A3DCanvas.class); public static final String CAMERA_POSITION = "camera_position"; private final LogicalLayer logicalLayer = new LogicalLayer(); private final A3DContainer container = new A3DContainer(this); private final A3DController controller; private final JScrollPane swingPane; private final LwjglAwtCanvas canvas; public A3DCanvas(final CoordinateReferenceSystem objectiveCRS, final Hints hints) throws LWJGLException { super(objectiveCRS, hints); canvas = initContext(); controller = new A3DController(this, logicalLayer); controller.init(); swingPane = new JScrollPane(canvas); swingPane.setBorder(null); swingPane.setWheelScrollingEnabled(false); swingPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); swingPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); swingPane.addComponentListener( new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { CanvasRenderer canvasRenderer = canvas.getCanvasRenderer(); if (canvasRenderer.getCamera() != null) { System.out.println("resized"); // tell our camera the correct new size canvasRenderer.getCamera().resize(canvas.getWidth(), canvas.getHeight()); // keep our aspect ratio the same. canvasRenderer .getCamera() .setFrustumPerspective( 45.0, canvas.getWidth() / (float) canvas.getHeight(), 1, 5000); } } }); Thread updater = new A3DPaintingUpdater(canvas, controller); updater.setPriority(Thread.MAX_PRIORITY); updater.start(); } @Override public synchronized void setObjectiveCRS(final CoordinateReferenceSystem crs) throws TransformException { throw new TransformException("You are not allowed to change CRS after creation on 3D canvas"); } @Override public A3DController getController() { return controller; } public A3DContainer getContainer2() { return container; } @Override public AbstractContainer getContainer() { return null; } public JComponent getComponent() { return swingPane; } public LwjglAwtCanvas getNativeCanvas() { return canvas; } private LwjglAwtCanvas initContext() throws LWJGLException { // refresher.addUpdater(controller); LwjglCanvasRenderer renderer = new LwjglCanvasRenderer(container); final DisplaySettings settings = new DisplaySettings(1, 1, 0, 0, 0, 32, 0, 4, false, false); final LwjglAwtCanvas canvas = new LwjglAwtCanvas(settings, renderer); canvas.setSize(new Dimension(100, 100)); canvas.setPreferredSize(new Dimension(1, 1)); canvas.setVisible(true); final AwtMouseWrapper mouseWrapper = new AwtMouseWrapper(canvas); final AwtKeyboardWrapper keyboardWrapper = new AwtKeyboardWrapper(canvas); final AwtFocusWrapper focusWrapper = new AwtFocusWrapper(canvas); final AwtMouseManager mouseManager = new AwtMouseManager(canvas); final PhysicalLayer pl = new PhysicalLayer(keyboardWrapper, mouseWrapper, focusWrapper); logicalLayer.registerInput(canvas, pl); logicalLayer.registerTrigger( new InputTrigger( new KeyPressedCondition(Key.H), new TriggerAction() { @Override public void perform(Canvas source, TwoInputStates arg1, double arg2) { if (source != canvas) { return; } } })); logicalLayer.registerTrigger( new InputTrigger( new KeyPressedCondition(Key.J), new TriggerAction() { @Override public void perform(Canvas source, TwoInputStates arg1, double arg2) { if (source != canvas) { return; } mouseManager.setCursor(MouseCursor.SYSTEM_DEFAULT); } })); // refresher.addCanvas(canvas); return canvas; } @Override protected RenderingContext getRenderingContext() { throw new UnsupportedOperationException("Not supported yet."); } }
/** * Lenght mesure handler * * @author Johann Sorel (Puzzle-GIS) * @module pending */ public class LenghtHandler implements CanvasHandler { private static final Logger LOGGER = Logging.getLogger(LenghtHandler.class); private static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory(); public static final List<Unit> UNITS = new ArrayList<Unit>(); static { UNITS.add(SI.KILOMETRE); UNITS.add(SI.METRE); UNITS.add(NonSI.MILE); UNITS.add(NonSI.INCH); } private final MouseListen mouseInputListener; private final List<Coordinate> coords = new ArrayList<Coordinate>(); private final LenghtDecoration deco = new LenghtDecoration(); private final JMap2D map; public LenghtHandler(final JMap2D map) { this.map = map; mouseInputListener = new MouseListen(); } /** {@inheritDoc } */ @Override public void install(final Component component) { mouseInputListener.install(component); map.addDecoration(0, deco); } /** {@inheritDoc } */ @Override public void uninstall(final Component component) { mouseInputListener.uninstall(component); map.removeDecoration(deco); } private void updateGeometry() { final List<Geometry> geoms = new ArrayList<Geometry>(); if (coords.size() == 1) { // single point geoms.add(GEOMETRY_FACTORY.createPoint(coords.get(0))); } else if (coords.size() > 1) { // line geoms.add(GEOMETRY_FACTORY.createLineString(coords.toArray(new Coordinate[coords.size()]))); } deco.setGeometries(geoms); } @Override public J2DCanvas getCanvas() { return map.getCanvas(); } // ---------------------PRIVATE CLASSES-------------------------------------- private class MouseListen extends MouseNavigatonListener { MouseListen() { super(map); } @Override public void mouseClicked(final MouseEvent e) { super.mouseClicked(e); final int mousebutton = e.getButton(); if (mousebutton == MouseEvent.BUTTON1) { // add a coordinate final AffineTransform2D trs = map.getCanvas().getController().getTransform(); try { final AffineTransform dispToObj = trs.createInverse(); final double[] crds = new double[] {e.getX(), e.getY()}; dispToObj.transform(crds, 0, crds, 0, 1); coords.add(new Coordinate(crds[0], crds[1])); updateGeometry(); } catch (NoninvertibleTransformException ex) { LOGGER.log(Level.WARNING, null, ex); } } else if (mousebutton == MouseEvent.BUTTON3) { // erase coordiantes coords.clear(); updateGeometry(); } } @Override public void mouseEntered(final MouseEvent e) { map.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); } } }
/** * @author Johann Sorel (Geomatys) * @module pending */ public class DefaultGetTile extends AbstractRequest implements GetTileRequest { /** Default logger for all GetMap requests. */ protected static final Logger LOGGER = Logging.getLogger(DefaultGetTile.class); /** The version to use for this webservice request. */ private int scale = 0; private int row = 0; private int col = 0; private String extension = ".png"; /** * Defines the server url for this request. * * @param serverURL The server url. */ protected DefaultGetTile(final String serverURL, final ClientSecurity security) { super(serverURL, security, null); } @Override protected String getSubPath() { final StringBuilder sb = new StringBuilder(); final String baseSub = super.getSubPath(); if (baseSub != null) { sb.append(baseSub); } sb.append('/').append(scale).append('/').append(col).append('/').append(row).append(extension); return sb.toString(); } @Override public int getScaleLevel() { return scale; } @Override public void setScaleLevel(final int level) { this.scale = level; } @Override public int getTileRow() { return row; } @Override public void setTileRow(final int row) { this.row = row; } @Override public int getTileCol() { return col; } @Override public void setTileCol(final int col) { this.col = col; } @Override public String getExtension() { return extension; } @Override public void setExtension(final String ext) { this.extension = ext; } }