/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.gwt.client.gfx.context; import org.geomajas.geometry.Coordinate; import org.geomajas.gwt.client.spatial.geometry.Geometry; import org.geomajas.gwt.client.spatial.geometry.LineString; import org.geomajas.gwt.client.spatial.geometry.LinearRing; import org.geomajas.gwt.client.spatial.geometry.MultiLineString; import org.geomajas.gwt.client.spatial.geometry.MultiPolygon; import org.geomajas.gwt.client.spatial.geometry.Polygon; /** * <p> * Decoder for geometry objects, that transforms them into strings that can be used as the "d" attribute of VML path * elements. * </p> * * @author Pieter De Graef */ public final class VmlPathDecoder { private VmlPathDecoder() { } /** * This function decodes a Geometry (line or polygon) to a path's d-attribute. * * @param geometry * The geometry to be decoded into a single path D attribute. * @return The D attribute value as a string. */ public static String decode(Geometry geometry) { return decode(geometry, 1.0f); } /** * This function decodes a Geometry (line or polygon) to a path's d-attribute. * * @param geometry * The geometry to be decoded into a single path D attribute. * @param scale * A scale value to apply on all the coordinates of the geometry before decoding. * @return The D attribute value as a string. */ public static String decode(Geometry geometry, float scale) { if (geometry == null) { return ""; } if (geometry instanceof LinearRing) { return decodeLinearRing((LinearRing) geometry, scale); } else if (geometry instanceof LineString) { return decodeLine((LineString) geometry, scale); } else if (geometry instanceof Polygon) { return decodePolygon((Polygon) geometry, scale); } else if (geometry instanceof MultiPolygon) { return decodeMultiPolygon((MultiPolygon) geometry, scale); } else if (geometry instanceof MultiLineString) { return decodeMultiLine((MultiLineString) geometry, scale); } return ""; } // ------------------------------------------------------------------------- // Private functions: // ------------------------------------------------------------------------- /** * Convert {@link LineString} to a VML string. * * @param line * line to convert * @param scale * scale to use * @return vml string representation of linestring */ private static String decodeLine(LineString line, float scale) { if (line == null || line.isEmpty()) { return ""; } StringBuilder buffer = new StringBuilder(); addCoordinates(buffer, line.getCoordinates(), scale); buffer.append(" e "); return buffer.toString(); } private static void addCoordinates(StringBuilder buffer, Coordinate[] coordinates, float scale) { buffer.append(" m "); buffer.append(parseValue(scale * coordinates[0].getX())); buffer.append(","); buffer.append(parseValue(scale * coordinates[0].getY())); buffer.append(" l"); for (int i = 1; i < coordinates.length; i++) { buffer.append(" "); buffer.append(parseValue(scale * coordinates[i].getX())); buffer.append(","); buffer.append(parseValue(scale * coordinates[i].getY())); } } private static String decodeLinearRing(LinearRing linearRing, float scale) { if (linearRing == null || linearRing.isEmpty()) { return ""; } StringBuilder buffer = new StringBuilder(); addCoordinates(buffer, linearRing.getCoordinates(), scale); buffer.append(" x "); return buffer.toString(); } private static String decodeMultiLine(MultiLineString multiLine, float scale) { int n = multiLine.getNumGeometries(); StringBuilder pstr = new StringBuilder(); for (int i = 0; i < n; i++) { pstr.append(decodeLine((LineString) multiLine.getGeometryN(i), scale)); } return pstr.toString(); } private static String decodePolygon(Polygon polygon, float scale) { if (polygon == null || polygon.isEmpty()) { return ""; } StringBuilder pstr = new StringBuilder(); pstr.append(decodeLinearRing(polygon.getExteriorRing(), scale)); for (int i = 0; i < polygon.getNumInteriorRing(); i++) { pstr.append(decodeLinearRing(polygon.getInteriorRingN(i), scale)); } return pstr.toString() + " e"; } private static String decodeMultiPolygon(MultiPolygon multipoly, float scale) { StringBuilder pstr = new StringBuilder(); for (int i = 0; i < multipoly.getNumGeometries(); i++) { pstr.append(decodePolygon((Polygon) multipoly.getGeometryN(i), scale)); } return pstr.toString(); } private static int parseValue(double value) { if (value > 21600) { return 21600; } else if (value < -21600) { return -21600; } return (int) Math.round(value); } }