001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.styling;
017:
018: import org.opengis.filter.expression.Expression;
019: import org.geotools.event.GTComponent;
020: import org.geotools.event.GTConstant;
021: import org.geotools.filter.ConstantExpression;
022:
023: /**
024: * A Graphic is a "graphical symbol" with an inherent shape, color(s), and
025: * possibly size.
026: *
027: * <p>
028: * A "graphic" can very informally be defined as "a little picture" and can be
029: * of either a raster or vector graphic source type. The term graphic is used
030: * since the term "symbol" is similar to "symbolizer" which is used in a
031: * difference context in SLD. The graphical symbol to display can be provided
032: * either as an external graphical resource or as a Mark.<br>
033: * Multiple external URLs and marks can be referenced with the proviso that
034: * they all provide equivalent graphics in different formats. The 'hot spot'
035: * to use for positioning the rendering at a point must either be inherent
036: * from the external format or be defined to be the "central point" of the
037: * graphic.
038: * </p>
039: *
040: * <p>
041: * The details of this object are taken from the <a
042: * href="https://portal.opengeospatial.org/files/?artifact_id=1188"> OGC
043: * Styled-Layer Descriptor Report (OGC 02-070) version 1.0.0.</a>:
044: * <pre><code>
045: * <xsd:element name="Graphic">
046: * <xsd:annotation>
047: * <xsd:documentation>
048: * A "Graphic" specifies or refers to a "graphic symbol" with inherent
049: * shape, size, and coloring.
050: * </xsd:documentation>
051: * </xsd:annotation>
052: * <xsd:complexType>
053: * <xsd:sequence>
054: * <xsd:choice minOccurs="0" maxOccurs="unbounded">
055: * <xsd:element ref="sld:ExternalGraphic"/>
056: * <xsd:element ref="sld:Mark"/>
057: * </xsd:choice>
058: * <xsd:sequence>
059: * <xsd:element ref="sld:Opacity" minOccurs="0"/>
060: * <xsd:element ref="sld:Size" minOccurs="0"/>
061: * <xsd:element ref="sld:Rotation" minOccurs="0"/>
062: * </xsd:sequence>
063: * </xsd:sequence>
064: * </xsd:complexType>
065: * </xsd:element>
066: * </code></pre>
067: * </p>
068: *
069: * <p>
070: * Renderers can ue this information when displaying styled features, though it
071: * must be remembered that not all renderers will be able to fully represent
072: * strokes as set out by this interface. For example, opacity may not be
073: * supported.
074: * </p>
075: *
076: * <p>
077: * Notes:
078: *
079: * <ul>
080: * <li>
081: * The graphical parameters and their values are derived from SVG/CSS2
082: * standards with names and semantics which are as close as possible.
083: * </li>
084: * </ul>
085: * </p>
086: *
087: * @task REVISIT: There are no setter methods in this interface, is this a
088: * problem?
089: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/api/src/main/java/org/geotools/styling/Graphic.java $
090: */
091: public interface Graphic extends GTComponent {
092: /**
093: * A default Graphic instance.
094: * <p>
095: * For some attributes the standard does not define a default, so a
096: * reasonable value is supplied.
097: * </p>
098: */
099: public static final Graphic DEFAULT = new ConstantGraphic() {
100: public ExternalGraphic[] getExternalGraphics() {
101: return ExternalGraphic.EXTERNAL_GRAPHICS_EMPTY;
102: }
103:
104: public Mark[] getMarks() {
105: return Mark.MARKS_EMPTY;
106: }
107:
108: public Symbol[] getSymbols() {
109: return Symbol.SYMBOLS_EMPTY;
110: }
111:
112: public Expression getOpacity() {
113: return ConstantExpression.ONE;
114: }
115:
116: public Expression getSize() {
117: return ConstantExpression.constant(16);
118: }
119:
120: public Displacement getDisplacement() {
121: return Displacement.DEFAULT;
122: }
123:
124: public Expression getRotation() {
125: return ConstantExpression.ZERO;
126: }
127:
128: public String getGeometryPropertyName() {
129: return "";
130: }
131: };
132:
133: /**
134: * Indicates an absense of graphic.
135: * <p>
136: * This value is used to indicate that the Graphics based opperation
137: * should be skipped. Aka this is used by Stroke.Stroke as place holders
138: * for GRAPHIC_FILL and GRAPHIC_STROKE.
139: * </p>
140: */
141: public static final Graphic NULL = new ConstantGraphic() {
142: public ExternalGraphic[] getExternalGraphics() {
143: return ExternalGraphic.EXTERNAL_GRAPHICS_EMPTY;
144: }
145:
146: public Mark[] getMarks() {
147: return Mark.MARKS_EMPTY;
148: }
149:
150: public Symbol[] getSymbols() {
151: return Symbol.SYMBOLS_EMPTY;
152: }
153:
154: public Expression getOpacity() {
155: return ConstantExpression.NULL;
156: }
157:
158: public Expression getSize() {
159: return ConstantExpression.NULL;
160: }
161:
162: public Displacement getDisplacement() {
163: return Displacement.NULL;
164: }
165:
166: public Expression getRotation() {
167: return ConstantExpression.NULL;
168: }
169:
170: public String getGeometryPropertyName() {
171: return "";
172: }
173: };
174:
175: /**
176: * Provides a list of external graphics which can be used to represent this
177: * graphic. Each one should be an equivalent representation but in a
178: * different format. If none are provided, or if none of the formats are
179: * supported, then the list of Marks should be used instead.
180: *
181: * @return An array of ExternalGraphics objects which should be equivalents
182: * but in different formats. If null is returned, use getMarks
183: * instead.
184: *
185: * @task REVISIT: The following may be a handy extra to have in this
186: * interface. public ExternalGraphic getExternalGraphic(String
187: * formats); return the first external graphic to match one of the
188: * given formats
189: */
190: ExternalGraphic[] getExternalGraphics();
191:
192: void setExternalGraphics(ExternalGraphic[] externalGraphics);
193:
194: void addExternalGraphic(ExternalGraphic externalGraphic);
195:
196: /**
197: * Provides a list of suitable marks which can be used to represent this
198: * graphic. These should only be used if no ExternalGraphic is provided,
199: * or if none of the external graphics formats are supported.
200: *
201: * @return An array of marks to use when displaying this Graphic. By
202: * default, a "square" with 50% gray fill and black outline with a
203: * size of 6 pixels (unless a size is specified) is provided.
204: */
205: Mark[] getMarks();
206:
207: void setMarks(Mark[] marks);
208:
209: void addMark(Mark mark);
210:
211: /**
212: * Provides a list of all the symbols which can be used to represent this
213: * graphic. A symbol is an ExternalGraphic, Mark or any other object which
214: * implements the Symbol interface. These are returned in the order they
215: * were set.
216: *
217: * @return An array of symbols to use when displaying this Graphic. By
218: * default, a "square" with 50% gray fill and black outline with a
219: * size of 6 pixels (unless a size is specified) is provided.
220: */
221: Symbol[] getSymbols();
222:
223: void setSymbols(Symbol[] symbols);
224:
225: void addSymbol(Symbol symbol);
226:
227: /**
228: * This specifies the level of translucency to use when rendering the graphic.<br>
229: * The value is encoded as a floating-point value between 0.0 and 1.0 with
230: * 0.0 representing totally transparent and 1.0 representing totally
231: * opaque, with a linear scale of translucency for intermediate values.<br>
232: * For example, "0.65" would represent 65% opacity. The default value is
233: * 1.0 (opaque).
234: *
235: * @return The opacity of the Graphic, where 0.0 is completely transparent
236: * and 1.0 is completely opaque.
237: */
238: Expression getOpacity();
239:
240: void setOpacity(Expression opacity);
241:
242: /**
243: * This paramteter gives the absolute size of the graphic in pixels encoded
244: * as a floating point number.
245: *
246: * <p>
247: * The default size of an image format (such as GIFD) is the inherent size
248: * of the image. The default size of a format without an inherent size
249: * (such as SVG) is defined to be 16 pixels in height and the
250: * corresponding aspect in width. If a size is specified, the height of
251: * the graphic will be scaled to that size and the corresponding aspect
252: * will be used for the width.
253: * </p>
254: *
255: * @return The size of the graphic. The default is context specific.
256: * Negative values are not possible.
257: */
258: Expression getSize();
259:
260: void setSize(Expression size);
261:
262: Displacement getDisplacement();
263:
264: void setDisplacement(Displacement offset);
265:
266: /**
267: * This parameter defines the rotation of a graphic in the clockwise
268: * direction about its centre point in decimal degrees. The value
269: * encoded as a floating point number.
270: *
271: * @return The angle of rotation in decimal degrees. Negative values
272: * represent counter-clockwise rotation. The default is 0.0 (no
273: * rotation).
274: */
275: Expression getRotation();
276:
277: void setRotation(Expression rotation);
278:
279: /**
280: * Getter for property geometryPropertyName.
281: *
282: * @return Value of property geometryPropertyName.
283: */
284: java.lang.String getGeometryPropertyName();
285:
286: /**
287: * Setter for property geometryPropertyName.
288: *
289: * @param geometryPropertyName New value of property geometryPropertyName.
290: */
291: void setGeometryPropertyName(java.lang.String geometryPropertyName);
292:
293: /**
294: * accepts a StyleVisitor - used by xmlencoder and other packages which
295: * need to walk the style tree
296: *
297: * @param visitor - the visitor object
298: */
299: void accept(StyleVisitor visitor);
300: }
301:
302: abstract class ConstantGraphic extends GTConstant implements Graphic {
303: private void cannotModifyConstant() {
304: throw new UnsupportedOperationException(
305: "Constant Graphic may not be modified");
306: }
307:
308: public void setExternalGraphics(ExternalGraphic[] externalGraphics) {
309: cannotModifyConstant();
310: }
311:
312: public void addExternalGraphic(ExternalGraphic externalGraphic) {
313: cannotModifyConstant();
314: }
315:
316: public void setMarks(Mark[] marks) {
317: cannotModifyConstant();
318: }
319:
320: public void addMark(Mark mark) {
321: cannotModifyConstant();
322: }
323:
324: public void setSymbols(Symbol[] symbols) {
325: cannotModifyConstant();
326: }
327:
328: public void addSymbol(Symbol symbol) {
329: cannotModifyConstant();
330: }
331:
332: public void setOpacity(Expression opacity) {
333: cannotModifyConstant();
334: }
335:
336: public void setSize(Expression size) {
337: cannotModifyConstant();
338: }
339:
340: public void setDisplacement(Displacement offset) {
341: cannotModifyConstant();
342: }
343:
344: public void setRotation(Expression rotation) {
345: cannotModifyConstant();
346: }
347:
348: public void setGeometryPropertyName(String geometryPropertyName) {
349: cannotModifyConstant();
350: }
351:
352: public void accept(StyleVisitor visitor) {
353: visitor.visit(this);
354: }
355: }
|