Package org.geomajas.internal.service

Source Code of org.geomajas.internal.service.StyleConverterServiceImpl

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 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.internal.service;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.geomajas.configuration.AttributeInfo;
import org.geomajas.configuration.CircleInfo;
import org.geomajas.configuration.FeatureInfo;
import org.geomajas.configuration.FeatureStyleInfo;
import org.geomajas.configuration.FontStyleInfo;
import org.geomajas.configuration.ImageInfo;
import org.geomajas.configuration.LabelStyleInfo;
import org.geomajas.configuration.NamedStyleInfo;
import org.geomajas.configuration.PrimitiveAttributeInfo;
import org.geomajas.configuration.PrimitiveType;
import org.geomajas.configuration.RectInfo;
import org.geomajas.configuration.SymbolInfo;
import org.geomajas.global.ExceptionCode;
import org.geomajas.layer.LayerException;
import org.geomajas.service.StyleConverterService;
import org.geomajas.sld.CssParameterInfo;
import org.geomajas.sld.ExternalGraphicInfo;
import org.geomajas.sld.FeatureTypeStyleInfo;
import org.geomajas.sld.FillInfo;
import org.geomajas.sld.FontInfo;
import org.geomajas.sld.GraphicInfo;
import org.geomajas.sld.GraphicInfo.ChoiceInfo;
import org.geomajas.sld.LineSymbolizerInfo;
import org.geomajas.sld.MarkInfo;
import org.geomajas.sld.NamedLayerInfo;
import org.geomajas.sld.ParameterValueTypeInfo;
import org.geomajas.sld.PointSymbolizerInfo;
import org.geomajas.sld.PolygonSymbolizerInfo;
import org.geomajas.sld.RuleInfo;
import org.geomajas.sld.StrokeInfo;
import org.geomajas.sld.StyledLayerDescriptorInfo;
import org.geomajas.sld.SymbolizerTypeInfo;
import org.geomajas.sld.TextSymbolizerInfo;
import org.geomajas.sld.UserStyleInfo;
import org.geomajas.sld.expression.ExpressionInfo;
import org.geomajas.sld.expression.LiteralTypeInfo;
import org.geomajas.sld.filter.AndInfo;
import org.geomajas.sld.filter.BBOXTypeInfo;
import org.geomajas.sld.filter.BeyondInfo;
import org.geomajas.sld.filter.BinaryComparisonOpTypeInfo;
import org.geomajas.sld.filter.BinaryLogicOpTypeInfo;
import org.geomajas.sld.filter.BinarySpatialOpTypeInfo;
import org.geomajas.sld.filter.ComparisonOpsTypeInfo;
import org.geomajas.sld.filter.ContainsInfo;
import org.geomajas.sld.filter.CrossesInfo;
import org.geomajas.sld.filter.DWithinInfo;
import org.geomajas.sld.filter.DisjointInfo;
import org.geomajas.sld.filter.DistanceBufferTypeInfo;
import org.geomajas.sld.filter.EqualsInfo;
import org.geomajas.sld.filter.FeatureIdTypeInfo;
import org.geomajas.sld.filter.FilterTypeInfo;
import org.geomajas.sld.filter.IntersectsInfo;
import org.geomajas.sld.filter.LogicOpsTypeInfo;
import org.geomajas.sld.filter.OrInfo;
import org.geomajas.sld.filter.OverlapsInfo;
import org.geomajas.sld.filter.PropertyIsBetweenTypeInfo;
import org.geomajas.sld.filter.PropertyIsEqualToInfo;
import org.geomajas.sld.filter.PropertyIsGreaterThanInfo;
import org.geomajas.sld.filter.PropertyIsGreaterThanOrEqualToInfo;
import org.geomajas.sld.filter.PropertyIsLessThanInfo;
import org.geomajas.sld.filter.PropertyIsLessThanOrEqualToInfo;
import org.geomajas.sld.filter.PropertyIsLikeTypeInfo;
import org.geomajas.sld.filter.PropertyIsNotEqualToInfo;
import org.geomajas.sld.filter.PropertyIsNullTypeInfo;
import org.geomajas.sld.filter.SpatialOpsTypeInfo;
import org.geomajas.sld.filter.TouchesInfo;
import org.geomajas.sld.filter.UnaryLogicOpTypeInfo;
import org.geomajas.sld.filter.WithinInfo;
import org.geomajas.sld.geometry.AbstractGeometryCollectionInfo;
import org.geomajas.sld.geometry.AbstractGeometryInfo;
import org.geomajas.sld.geometry.CoordTypeInfo;
import org.geomajas.sld.geometry.CoordinatesTypeInfo;
import org.geomajas.sld.geometry.GeometryMemberInfo;
import org.geomajas.sld.geometry.InnerBoundaryIsInfo;
import org.geomajas.sld.geometry.LineStringTypeInfo;
import org.geomajas.sld.geometry.LinearRingTypeInfo;
import org.geomajas.sld.geometry.MultiGeometryInfo;
import org.geomajas.sld.geometry.MultiLineStringInfo;
import org.geomajas.sld.geometry.MultiPointInfo;
import org.geomajas.sld.geometry.MultiPolygonInfo;
import org.geomajas.sld.geometry.OuterBoundaryIsInfo;
import org.geomajas.sld.geometry.PointTypeInfo;
import org.geomajas.sld.geometry.PolygonTypeInfo;
import org.springframework.stereotype.Component;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.WKTWriter;

/**
* Default implementation of {@link StyleConverterService}. Supports named layers and user styles only.
*
* @author Jan De Moerloose
*
*/
@Component
public class StyleConverterServiceImpl implements StyleConverterService {

  public NamedStyleInfo convert(StyledLayerDescriptorInfo styledLayerDescriptorInfo, FeatureInfo featureInfo,
      String layerName, String styleName) throws LayerException {
    NamedLayerInfo namedLayerInfo = null;
    // find first named layer or find by name
    for (StyledLayerDescriptorInfo.ChoiceInfo choice : styledLayerDescriptorInfo.getChoiceList()) {
      // we only support named layers, pick the right name or the first one
      if (choice.ifNamedLayer()) {
        if (layerName != null) {
          if (layerName.equals(choice.getNamedLayer().getName())) {
            namedLayerInfo = choice.getNamedLayer();
            break;
          }
        }
        if (namedLayerInfo == null) {
          namedLayerInfo = choice.getNamedLayer();
        }
      }
    }
    if (namedLayerInfo == null) {
      throw new LayerException(ExceptionCode.INVALID_SLD, styledLayerDescriptorInfo.getName(), layerName);
    }

    UserStyleInfo userStyleInfo = null;
    for (NamedLayerInfo.ChoiceInfo choice : namedLayerInfo.getChoiceList()) {
      // we only support user styles, pick the right name or the first
      if (choice.ifUserStyle()) {
        if (styleName != null) {
          if (styleName.equals(choice.getUserStyle().getName())) {
            userStyleInfo = choice.getUserStyle();
            break;
          }
        }
        if (userStyleInfo == null) {
          userStyleInfo = choice.getUserStyle();
        }
      }
    }
    if (userStyleInfo == null) {
      throw new LayerException(ExceptionCode.INVALID_SLD, styledLayerDescriptorInfo.getName(), layerName);
    }

    NamedStyleInfo namedStyleInfo = convert(userStyleInfo, featureInfo);
    if (namedStyleInfo.getName() == null) {
      namedStyleInfo.setName(styleName);
    }
    for (FeatureStyleInfo featureStyleInfo : namedStyleInfo.getFeatureStyles()) {
      if (featureStyleInfo.getName() == null) {
        featureStyleInfo.setName(namedLayerInfo.getName());
      }
      featureStyleInfo.setStyleId(namedStyleInfo.getName() + featureStyleInfo.getIndex());
    }
    return namedStyleInfo;
  }

  private NamedStyleInfo convert(UserStyleInfo userStyle, FeatureInfo featureInfo) {
    NamedStyleInfo namedStyleInfo = new NamedStyleInfo();
    LabelStyleInfo labelStyleInfo = new LabelStyleInfo();
    List<FeatureStyleInfo> featureStyleInfos = new ArrayList<FeatureStyleInfo>();
    for (FeatureTypeStyleInfo featureTypeStyleInfo : userStyle.getFeatureTypeStyleList()) {
      int styleIndex = 0;
      for (RuleInfo ruleInfo : featureTypeStyleInfo.getRuleList()) {
        FeatureStyleInfo featureStyleInfo = new FeatureStyleInfo();
        if (ruleInfo.getChoice() != null) {
          if (ruleInfo.getChoice().ifFilter()) {
            featureStyleInfo.setFormula(convertFormula(ruleInfo.getChoice().getFilter(), featureInfo));
          }
        }
        for (SymbolizerTypeInfo symbolizerTypeInfo : ruleInfo.getSymbolizerList()) {
          if (symbolizerTypeInfo instanceof PointSymbolizerInfo) {
            PointSymbolizerInfo pointInfo = (PointSymbolizerInfo) symbolizerTypeInfo;
            convertSymbol(featureStyleInfo, pointInfo);
          } else if (symbolizerTypeInfo instanceof LineSymbolizerInfo) {
            LineSymbolizerInfo lineInfo = (LineSymbolizerInfo) symbolizerTypeInfo;
            convertStroke(featureStyleInfo, lineInfo.getStroke());
          } else if (symbolizerTypeInfo instanceof PolygonSymbolizerInfo) {
            PolygonSymbolizerInfo polygonInfo = (PolygonSymbolizerInfo) symbolizerTypeInfo;
            convertFill(featureStyleInfo, polygonInfo.getFill());
            convertStroke(featureStyleInfo, polygonInfo.getStroke());
          } else if (symbolizerTypeInfo instanceof TextSymbolizerInfo) {
            TextSymbolizerInfo textInfo = (TextSymbolizerInfo) symbolizerTypeInfo;
            labelStyleInfo.setFontStyle(convertFont(textInfo.getFont()));
            for (ExpressionInfo expr : textInfo.getLabel().getExpressionList()) {
              labelStyleInfo.setLabelAttributeName(expr.getValue());
            }
            convertFontFill(labelStyleInfo.getFontStyle(), textInfo.getFill());
            FeatureStyleInfo background = new FeatureStyleInfo();
            if (textInfo.getHalo() != null) {
              convertFill(background, textInfo.getHalo().getFill());
            }
            labelStyleInfo.setBackgroundStyle(background);
          }
        }
        if (featureStyleInfo.getStrokeColor() == null && featureStyleInfo.getFillColor() != null) {
          // avoid default stroke by setting invisible
          featureStyleInfo.setStrokeColor("black");
          featureStyleInfo.setStrokeOpacity(0);
          featureStyleInfo.setStrokeWidth(0);
        }
        featureStyleInfo.setIndex(styleIndex++);
        featureStyleInfo.setName(ruleInfo.getTitle() != null ? ruleInfo.getTitle() : ruleInfo.getName());
        featureStyleInfos.add(featureStyleInfo);
      }
    }
    namedStyleInfo.setName(userStyle.getTitle() != null ? userStyle.getTitle() : userStyle.getName());
    namedStyleInfo.setFeatureStyles(featureStyleInfos);
    namedStyleInfo.setLabelStyle(labelStyleInfo);
    return namedStyleInfo;
  }

  private void convertSymbol(FeatureStyleInfo featureStyleInfo, PointSymbolizerInfo pointInfo) {
    GraphicInfo graphic = pointInfo.getGraphic();
    SymbolInfo symbol = new SymbolInfo();

    if (graphic.getChoiceList().size() > 0) {
      ChoiceInfo choice = graphic.getChoiceList().get(0);
      if (choice.ifExternalGraphic()) {
        ExternalGraphicInfo externalGraphic = choice.getExternalGraphic();
        String href = externalGraphic.getOnlineResource().getHref().getHref();
        ImageInfo image = new ImageInfo();
        image.setHref(href);
        // SLD has no selection concept + no default: what to do ?
        image.setSelectionHref(href);
        image.setHeight((int) Float.parseFloat(getParameterValue(graphic.getSize())));
        symbol.setImage(image);
      } else if (choice.ifMark()) {
        MarkInfo mark = choice.getMark();
        String name = mark.getWellKnownName().getWellKnownName();
        if (name.equalsIgnoreCase("square")) {
          RectInfo rect = new RectInfo();
          rect.setH(Float.parseFloat(getParameterValue(graphic.getSize())));
          rect.setW(Float.parseFloat(getParameterValue(graphic.getSize())));
          symbol.setRect(rect);
        } else {
          // should treat everything else as circle ?!
          CircleInfo circle = new CircleInfo();
          circle.setR(0.5F * Float.parseFloat(getParameterValue(graphic.getSize())));
          symbol.setCircle(circle);
        }
        convertFill(featureStyleInfo, mark.getFill());
        convertStroke(featureStyleInfo, mark.getStroke());
      }
    }
    featureStyleInfo.setSymbol(symbol);
  }

  private void convertFontFill(FontStyleInfo fontStyle, FillInfo fill) {
    if (fill != null) {
      Map<String, String> cssMap = getLiteralMap(fill.getCssParameterList());
      fontStyle.setColor(cssMap.get("fill"));
      if (cssMap.containsKey("fill-opacity")) {
        fontStyle.setOpacity(Float.parseFloat(cssMap.get("fill-opacity")));
      }
    }
  }

  private FontStyleInfo convertFont(FontInfo font) {
    FontStyleInfo fontStyle = new FontStyleInfo();
    if (font == null) {
      fontStyle.applyDefaults();
    } else {
      Map<String, String> cssMap = getLiteralMap(font.getCssParameterList());
      fontStyle.setFamily(cssMap.get("font-family"));
      if (cssMap.containsKey("font-size")) {
        fontStyle.setSize(Integer.parseInt(cssMap.get("font-size")));
      }
      fontStyle.setStyle(cssMap.get("font-style"));
      fontStyle.setWeight(cssMap.get("font-weight"));
    }
    return fontStyle;
  }

  private void convertFill(FeatureStyleInfo featureStyleInfo, FillInfo fill) {
    if (fill != null) {
      Map<String, String> cssMap = getLiteralMap(fill.getCssParameterList());
      if (cssMap.containsKey("fill")) {
        featureStyleInfo.setFillColor(cssMap.get("fill"));
      }
      if (cssMap.containsKey("fill-opacity")) {
        featureStyleInfo.setFillOpacity(Float.parseFloat(cssMap.get("fill-opacity")));
      }
      if (fill.getGraphicFill() != null) {
        GraphicInfo graphic = fill.getGraphicFill().getGraphic();
        for (GraphicInfo.ChoiceInfo choice : graphic.getChoiceList()) {
          if (choice.ifExternalGraphic()) {
            // can't handle this
          } else if (choice.ifMark()) {
            MarkInfo mark = (MarkInfo) choice.getMark();
            if (mark.getFill() != null) {
              convertFill(featureStyleInfo, mark.getFill());
            }
            if (mark.getStroke() != null) {
              convertStroke(featureStyleInfo, mark.getStroke());
            }
          }
        }
      }
    }
  }

  private void convertStroke(FeatureStyleInfo featureStyleInfo, StrokeInfo stroke) {
    if (stroke != null) {
      Map<String, String> cssMap = getLiteralMap(stroke.getCssParameterList());
      // not supported are "stroke-linejoin", "stroke-linecap", and "stroke-dashoffset"
      featureStyleInfo.setStrokeColor(cssMap.get("stroke"));
      if (cssMap.containsKey("stroke-opacity")) {
        featureStyleInfo.setStrokeOpacity(Float.parseFloat(cssMap.get("stroke-opacity")));
      }
      if (cssMap.containsKey("stroke-width")) {
        featureStyleInfo.setStrokeWidth((int) Float.parseFloat(cssMap.get("stroke-width")));
      }
      if (cssMap.containsKey("stroke-dasharray")) {
        featureStyleInfo.setDashArray(cssMap.get("stroke-dasharray"));
      }
    }
  }

  private String convertFormula(FilterTypeInfo filter, FeatureInfo featureInfo) {
    if (filter.ifComparisonOps()) {
      return toComparison(filter.getComparisonOps(), featureInfo);
    } else if (filter.ifFeatureIdList()) {
      return toFeatureIds(filter.getFeatureIdList());
    } else if (filter.ifLogicOps()) {
      return toLogic(filter.getLogicOps(), featureInfo);
    } else if (filter.ifSpatialOps()) {
      return toSpatial(filter.getSpatialOps());
    }
    return null;
  }

  private String toLogic(LogicOpsTypeInfo logicOps, FeatureInfo featureInfo) {
    if (logicOps instanceof UnaryLogicOpTypeInfo) {
      UnaryLogicOpTypeInfo unary = (UnaryLogicOpTypeInfo) logicOps;
      if (unary.ifComparisonOps()) {
        return "NOT " + toComparison(unary.getComparisonOps(), featureInfo);
      } else if (unary.ifLogicOps()) {
        return "NOT " + toLogic(unary.getLogicOps(), featureInfo);
      } else if (unary.ifSpatialOps()) {
        return "NOT " + toSpatial(unary.getSpatialOps());
      }

    } else if (logicOps instanceof BinaryLogicOpTypeInfo) {
      BinaryLogicOpTypeInfo binary = (BinaryLogicOpTypeInfo) logicOps;
      String[] expressions = new String[2];
      for (int i = 0; i < 2; i++) {
        if (binary.getChoiceList().get(i).ifComparisonOps()) {
          expressions[i] = toComparison(binary.getChoiceList().get(i).getComparisonOps(), featureInfo);
        } else if (binary.getChoiceList().get(i).ifLogicOps()) {
          expressions[i] = toLogic(binary.getChoiceList().get(i).getLogicOps(), featureInfo);
        } else if (binary.getChoiceList().get(i).ifSpatialOps()) {
          expressions[i] = toSpatial(binary.getChoiceList().get(i).getSpatialOps());
        }
      }
      if (binary instanceof OrInfo) {
        return "(" + expressions[0] + ") OR (" + expressions[1] + ")";
      } else if (binary instanceof AndInfo) {
        return "(" + expressions[0] + ") AND (" + expressions[1] + ")";
      }
    }
    return null;
  }

  private String toSpatial(SpatialOpsTypeInfo spatialOps) {
    if (spatialOps instanceof BBOXTypeInfo) {
      BBOXTypeInfo bbox = (BBOXTypeInfo) spatialOps;
      String propertyName = bbox.getPropertyName().getValue();
      String coordinates = null;
      if (bbox.getBox().ifCoordinates()) {
        String cs = bbox.getBox().getCoordinates().getCs();
        String ts = bbox.getBox().getCoordinates().getTs();
        String ds = bbox.getBox().getCoordinates().getDecimal();
        coordinates = bbox.getBox().getCoordinates().getString().trim().replace(ds, "ds").replace(ts, "ts")
            .replace(cs, "cs").replace("ds", ".").replace("ts", ",").replace("cs", ",");
      } else {
        for (CoordTypeInfo coord : bbox.getBox().getCoordList()) {
          coordinates += coord.getX() + "," + coord.getY() + (coordinates == null ? "," : "");
        }
      }
      return "BBOX (" + propertyName + "," + coordinates + ")";
    } else if (spatialOps instanceof BinarySpatialOpTypeInfo) {
      BinarySpatialOpTypeInfo binary = (BinarySpatialOpTypeInfo) spatialOps;
      String propertyName = binary.getPropertyName().getValue();
      if (binary.ifGeometry()) {
        Geometry geometry = null;
        WKTWriter writer = new WKTWriter();
        GeometryFactory factory = new GeometryFactory();
        AbstractGeometryInfo geom = binary.getGeometry();
        geometry = toGeometry(factory, geom);
        String wkt = writer.write(geometry);
        if (binary instanceof ContainsInfo) {
          return "CONTAINS(" + propertyName + "," + wkt + ")";
        } else if (binary instanceof CrossesInfo) {
          return "CROSSES(" + propertyName + "," + wkt + ")";
        } else if (binary instanceof DisjointInfo) {
          return "DISJOINT(" + propertyName + "," + wkt + ")";
        } else if (binary instanceof EqualsInfo) {
          return "EQUALS(" + propertyName + "," + wkt + ")";
        } else if (binary instanceof IntersectsInfo) {
          return "INTERSECTS(" + propertyName + "," + wkt + ")";
        } else if (binary instanceof OverlapsInfo) {
          return "OVERLAPS(" + propertyName + "," + wkt + ")";
        } else if (binary instanceof TouchesInfo) {
          return "TOUCHES(" + propertyName + "," + wkt + ")";
        } else if (binary instanceof WithinInfo) {
          return "WITHIN(" + propertyName + "," + wkt + ")";
        }
      } else if (spatialOps instanceof DistanceBufferTypeInfo) {
        DistanceBufferTypeInfo distanceBuffer = (DistanceBufferTypeInfo) spatialOps;
        AbstractGeometryInfo geom = distanceBuffer.getGeometry();
        GeometryFactory factory = new GeometryFactory();
        Geometry geometry = toGeometry(factory, geom);
        WKTWriter writer = new WKTWriter();
        String wkt = writer.write(geometry);
        String units = distanceBuffer.getDistance().getUnits();
        String distance = distanceBuffer.getDistance().getValue();
        if (distanceBuffer instanceof DWithinInfo) {
          return "DWITHIN(" + propertyName + "," + wkt + "," + distance + "," + units + ")";
        } else if (distanceBuffer instanceof BeyondInfo) {
          return "BEYOND(" + propertyName + "," + wkt + "," + distance + "," + units + ")";
        }
      }
    }
    return null;
  }

  private Geometry toGeometry(GeometryFactory factory, AbstractGeometryInfo geom) {
    Geometry geometry = null;
    if (geom instanceof AbstractGeometryCollectionInfo) {
      AbstractGeometryCollectionInfo geomCollection = (AbstractGeometryCollectionInfo) geom;
      List<GeometryMemberInfo> members = geomCollection.getGeometryMemberList();
      if (geom instanceof MultiPointInfo) {
        Point[] points = new Point[members.size()];
        for (int i = 0; i < members.size(); i++) {
          points[i] = (Point) toSimpleGeometry(factory, members.get(i).getGeometry());
        }
        geometry = factory.createMultiPoint(points);
      } else if (geom instanceof MultiLineStringInfo) {
        LineString[] lines = new LineString[members.size()];
        for (int i = 0; i < members.size(); i++) {
          lines[i] = (LineString) toSimpleGeometry(factory, members.get(i).getGeometry());
        }
        geometry = factory.createMultiLineString(lines);
      } else if (geom instanceof MultiPolygonInfo) {
        Polygon[] polygons = new Polygon[members.size()];
        for (int i = 0; i < members.size(); i++) {
          polygons[i] = (Polygon) toSimpleGeometry(factory, members.get(i).getGeometry());
        }
        geometry = factory.createMultiPolygon(polygons);
      } else if (geom instanceof MultiGeometryInfo) {
        Geometry[] geometries = new Geometry[members.size()];
        for (int i = 0; i < members.size(); i++) {
          geometries[i] = toSimpleGeometry(factory, members.get(i).getGeometry());
        }
        geometry = factory.createGeometryCollection(geometries);
      }
    } else {
      geometry = toSimpleGeometry(factory, geom);
    }
    return geometry;
  }

  private Geometry toSimpleGeometry(GeometryFactory factory, AbstractGeometryInfo geom) {
    Geometry geometry = null;
    if (geom instanceof PointTypeInfo) {
      PointTypeInfo point = (PointTypeInfo) geom;
      if (point.ifCoord()) {
        geometry = factory.createPoint(getCoordinates(Collections.singletonList(point.getCoord()))[0]);
      } else if (point.ifCoordinates()) {
        geometry = factory.createPoint(getCoordinates(point.getCoordinates())[0]);
      }
    } else if (geom instanceof LineStringTypeInfo) {
      LineStringTypeInfo linestring = (LineStringTypeInfo) geom;
      if (linestring.ifCoordList()) {
        geometry = factory.createLineString(getCoordinates(linestring.getCoordList()));
      } else if (linestring.ifCoordinates()) {
        geometry = factory.createLineString(getCoordinates(linestring.getCoordinates()));
      }
    } else if (geom instanceof PolygonTypeInfo) {
      PolygonTypeInfo polygon = (PolygonTypeInfo) geom;
      OuterBoundaryIsInfo outer = polygon.getOuterBoundaryIs();
      LinearRing shell = toLinearRing(factory, outer.getLinearRing());
      LinearRing[] holes = new LinearRing[polygon.getInnerBoundaryIList().size()];
      int i = 0;
      for (InnerBoundaryIsInfo inner : polygon.getInnerBoundaryIList()) {
        holes[i++] = toLinearRing(factory, inner.getLinearRing());
      }
      geometry = factory.createPolygon(shell, holes);
    }
    return geometry;
  }

  private LinearRing toLinearRing(GeometryFactory factory, LinearRingTypeInfo linearRing) {
    LinearRing ring = null;
    if (linearRing.ifCoordList()) {
      ring = factory.createLinearRing(getCoordinates(linearRing.getCoordList()));
    } else if (linearRing.ifCoordinates()) {
      ring = factory.createLinearRing(getCoordinates(linearRing.getCoordinates()));
    }
    return ring;
  }

  private Coordinate[] getCoordinates(List<CoordTypeInfo> coords) {
    Coordinate[] result = new Coordinate[coords.size()];
    int i = 0;
    for (CoordTypeInfo coordinate : coords) {
      result[i++] = new Coordinate(coordinate.getX().doubleValue(), coordinate.getY().doubleValue());
    }
    return result;
  }

  private Coordinate[] getCoordinates(CoordinatesTypeInfo coords) {
    String[] coordinates = coords.getString().split(
        Pattern.quote(coords.getCs()) + "|" + Pattern.quote(coords.getTs()));
    Coordinate[] result = new Coordinate[coordinates.length / 2];
    for (int i = 0; i < coordinates.length; i += 2) {
      double x = Double.parseDouble(coordinates[i].replace(coords.getDecimal(), "."));
      double y = Double.parseDouble(coordinates[i + 1].replace(coords.getDecimal(), "."));
      result[i / 2] = new Coordinate(x, y);
    }
    return result;
  }

  private String toFeatureIds(List<FeatureIdTypeInfo> featureIds) {
    StringBuilder stringBuilder = new StringBuilder("IN (");
    for (Iterator<FeatureIdTypeInfo> it = featureIds.iterator(); it.hasNext();) {
      stringBuilder.append("'").append(it.next().getFid()).append("'");
      stringBuilder.append(it.hasNext() ? "," : ")");
    }
    return stringBuilder.toString();
  }

  private String toComparison(ComparisonOpsTypeInfo coOps, FeatureInfo featureInfo) {
    if (coOps instanceof BinaryComparisonOpTypeInfo) {
      BinaryComparisonOpTypeInfo binary = (BinaryComparisonOpTypeInfo) coOps;
      String propertyName = binary.getExpressionList().get(0).getValue();
      String propertyValue = binary.getExpressionList().get(1).getValue();
      PrimitiveType type = PrimitiveType.STRING;
      for (AttributeInfo attributeInfo : featureInfo.getAttributes()) {
        if (attributeInfo.getName().equals(propertyName)) {
          if (attributeInfo instanceof PrimitiveAttributeInfo) {
            type = ((PrimitiveAttributeInfo) attributeInfo).getType();
          }
        }
      }
      switch (type) {
        case BOOLEAN:
          propertyValue = propertyValue.toUpperCase();
          break;
        case DATE:
        case IMGURL:
        case STRING:
        case URL:
          propertyValue = "'" + propertyValue + "'";
          break;

      }
      if (binary instanceof PropertyIsEqualToInfo) {
        return propertyName + " = " + propertyValue;
      } else if (binary instanceof PropertyIsGreaterThanInfo) {
        return propertyName + " > " + propertyValue;
      } else if (binary instanceof PropertyIsGreaterThanOrEqualToInfo) {
        return propertyName + " >= " + propertyValue;
      } else if (binary instanceof PropertyIsLessThanInfo) {
        return propertyName + " < " + propertyValue;
      } else if (binary instanceof PropertyIsLessThanOrEqualToInfo) {
        return propertyName + " <= " + propertyValue;
      } else if (binary instanceof PropertyIsNotEqualToInfo) {
        return propertyName + " != " + propertyValue;
      }
    } else {
      if (coOps instanceof PropertyIsBetweenTypeInfo) {
        PropertyIsBetweenTypeInfo isBetween = (PropertyIsBetweenTypeInfo) coOps;
        String lower = isBetween.getLowerBoundary().getExpression().getValue();
        String upper = isBetween.getUpperBoundary().getExpression().getValue();
        String propertyName = isBetween.getExpression().getValue();
        return propertyName + " BETWEEN " + lower + " AND " + upper;
      } else if (coOps instanceof PropertyIsLikeTypeInfo) {
        PropertyIsLikeTypeInfo isLike = (PropertyIsLikeTypeInfo) coOps;
        String propertyName = isLike.getPropertyName().getValue();
        return propertyName + " LIKE '" + isLike.getLiteral().getValue() + "'";
      } else if (coOps instanceof PropertyIsNullTypeInfo) {
        PropertyIsNullTypeInfo isNull = (PropertyIsNullTypeInfo) coOps;
        if (isNull.ifLiteral()) {
          String literal = isNull.getLiteral().getValue();
          return "'" + literal + "' IS NULL ";
        } else {
          String propertyName = isNull.getPropertyName().getValue();
          return propertyName + " IS NULL ";
        }
      }
    }
    return null;
  }

  private Map<String, String> getLiteralMap(List<CssParameterInfo> css) {
    HashMap<String, String> result = new HashMap<String, String>();
    if (css != null) {
      for (CssParameterInfo cssParameter : css) {
        if (cssParameter.getValue() != null) {
          result.put(cssParameter.getName(), cssParameter.getValue());
        } else if (cssParameter.getExpressionList().size() > 0) {
          ExpressionInfo expression = cssParameter.getExpressionList().get(0);
          if (expression instanceof LiteralTypeInfo) {
            result.put(cssParameter.getName(), expression.getValue());
          }
        }
      }
    }
    return result;
  }

  private String getParameterValue(ParameterValueTypeInfo parameter) {
    if (parameter.getValue() != null) {
      return parameter.getValue();
    } else if (parameter.getExpressionList().size() > 0) {
      ExpressionInfo expression = parameter.getExpressionList().get(0);
      if (expression instanceof LiteralTypeInfo) {
        return expression.getValue();
      }
    }
    return null;
  }

}
TOP

Related Classes of org.geomajas.internal.service.StyleConverterServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.