Geotools条件样式基于属性

时间:2013-12-06 13:42:33

标签: java geotools

如何根据属性的值不同地设置图层的不同元素?

例如,我有时区数据,其中包含一个将1到8之间的整数关联到每个时区的属性,以便为地图上的时区着色。如何将样式与属性的每个值相关联,并使用它为不同颜色的时区着色?

1 个答案:

答案 0 :(得分:2)

这个答案适用于Geotools 9.2

以下是您可以采用的示例,请参阅以下有关如何将其应用于您的要求的一些建议。

这个例子是关于多边形的。它具有不同的选定和可见特征样式以及小尺度和大尺度:

protected final StyleFactory styleFactory =
  CommonFactoryFinder.getStyleFactory(GeoTools.getDefaultHints());
protected final FilterFactory2 filterFactory =
  CommonFactoryFinder.getFilterFactory2();

protected Rule createLayerRule
  ( Color outlineColor
  , float strokeWidth
  , Color fillColor
  , float opacity
  , Filter filter
  , double minScaleDenominator
  , double maxScaleDenominator)
{
  Stroke stroke =
      outlineColor != null
    ? styleFactory.createStroke
       ( filterFactory.literal(outlineColor)
       , filterFactory.literal(strokeWidth)
       , filterFactory.literal(opacity))
    : null;//Stroke.NULL;
  Fill fill = 
      fillColor != null 
    ? styleFactory.createFill
       ( filterFactory.literal(fillColor)
       , filterFactory.literal(opacity))
    : null;//Fill.NULL;

  PolygonSymbolizer symbolizer = 
    styleFactory.createPolygonSymbolizer(stroke, fill, null);

  return createRule(filter, minScaleDenominator, maxScaleDenominator, symbolizer);
}

// IDs of visible features, programmatically updated. 
protected final Set<FeatureId> visibleFeatureIDs = new HashSet<FeatureId>();

// IDs of selected features, programmatically updated. 
protected final Set<FeatureId> selectedFeatureIDs = new HashSet<FeatureId>();

protected Style createLayerStyle()
{
  Filter selectionFilter = filterFactory.id(selectedFeatureIDs);
  Filter visibilityFilter = filterFactory.and
    ( Arrays.asList
        ( filterFactory.not
            (selectionFilter)
        , filterFactory.id(visibleFeatureIDs)
        )
    );
  FeatureTypeStyle fts = styleFactory.createFeatureTypeStyle
    ( new Rule[]
      {
        // hope constants below are self explaining
        createLayerRule
          ( SELECTED_OUTLINE_COLOR 
          , STROKE_WIDTH_LARGE_SCALE
          , SELECTED_FILL_COLOR
          , SELECTED_OPACITY
          , selectionFilter
          , STYLE_SCALE_LIMIT
          , Double.NaN)
      , createLayerRule
          ( UNSELECTED_OUTLINE_COLOR
          , STROKE_WIDTH_LARGE_SCALE
          , UNSELECTED_FILL_COLOR
          , UNSELECTED_OPACITY
          , visibilityFilter
          , STYLE_SCALE_LIMIT
          , Double.NaN)
      , createLayerRule
          ( SELECTED_OUTLINE_COLOR
          , STROKE_WIDTH_SMALL_SCALE
          , SELECTED_FILL_COLOR
          , SELECTED_OPACITY
          , selectionFilter
          , Double.NaN
          , STYLE_SCALE_LIMIT)
      , createLayerRule
          ( UNSELECTED_OUTLINE_COLOR
          , STROKE_WIDTH_SMALL_SCALE
          , UNSELECTED_FILL_COLOR
          , UNSELECTED_OPACITY
          , visibilityFilter
          , Double.NaN
          , STYLE_SCALE_LIMIT)
      }
    );

  Style style = styleFactory.createStyle();
  style.featureTypeStyles().add(fts);

  return style;
}

// layer creation
FeatureLayer someMethode()
{
  ...
  FeatureLayer layer = new FeatureLayer
    ( dataStore.getFeatureSource()
    , createLayerStyle()
    , "Zipcodes"
    );
  ...
  return layer;
}

// style update if visible or selected features have changed
void someOtherMethod(FeatureLayer layer)
{
   ... // update selectedFeatureIDs or visibleFeatureIDs
   layer.setStyle(createLayerStyle());
}

当然,优化是可能的,也是受欢迎的。

根据您的要求,以下内容可能有所帮助:

  1. 如果您想要为所有比例设置一种样式(或者对于小型和大型比例为16),则需要8条规则(请参阅上面的createRule(..))。
  2. 使用FilterFactory.equals(Expression, Expression)定义8个过滤器,其中第一个表达式的类型为AttributeExpressionImpl,第二个类型为LiteralExpressionImpl
  3. 请注意,FilterFactory2中还有另一种方法equal(没有 s