/* * GeoTools - The Open Source Java GIS Tookit * http://geotools.org * * (C) 2006-2008, Open Source Geospatial Foundation (OSGeo) * * This file is hereby placed into the Public Domain. This means anyone is * free to do whatever they wish with this file. Use it well and enjoy! */ package org.geotools.demo.filter.function; import java.awt.Color; import java.io.File; import java.util.ArrayList; import java.util.List; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import net.miginfocom.swing.MigLayout; import org.geotools.data.FeatureSource; import org.geotools.data.FileDataStore; import org.geotools.data.FileDataStoreFinder; import org.geotools.factory.CommonFactoryFinder; import org.geotools.map.DefaultMapContext; import org.geotools.map.MapContext; import org.geotools.styling.SLD; import org.geotools.styling.Style; import org.geotools.styling.StyleFactory; import org.geotools.styling.TextSymbolizer; import org.geotools.swing.JMapFrame; import org.geotools.swing.data.JFileDataStoreChooser; import org.geotools.swing.wizard.JPage; import org.geotools.swing.wizard.JWizard; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.FeatureType; import org.opengis.feature.type.PropertyDescriptor; import org.opengis.filter.FilterFactory; /** * Illustrates the use of a filter function to create compound feature labels * from two feature attributes * * @author Michael Bedward */ public class CompoundLabel { public static void main(String[] args) throws Exception { // display a data store file chooser dialog for shapefiles File file = JFileDataStoreChooser.showOpenFile("shp", null); if (file == null) { return; } CompoundLabel me = new CompoundLabel(); me.displayShapefile(file); } /** * Creates a style that includes labels formed from two feature * attributes selected by the user, then displays the shapefile using * this style. */ private void displayShapefile(File file) throws Exception { FileDataStore store = FileDataStoreFinder.getDataStore(file); FeatureSource featureSource = store.getFeatureSource(); Style style = createLabelStyle(featureSource); if (style != null) { MapContext map = new DefaultMapContext(); map.setTitle("Compound feature labels"); map.addLayer(featureSource, style); JMapFrame.showMap(map); } } /** * Prompt the user to select the two feature attributes to use for * labelling and create a new Style instance. */ private Style createLabelStyle(FeatureSource featureSource) { FeatureType schema = featureSource.getSchema(); List<String> fieldNames = new ArrayList<String>(); for (PropertyDescriptor desc : schema.getDescriptors()) { if (String.class.isAssignableFrom( desc.getType().getBinding() )) { fieldNames.add(desc.getName().getLocalPart()); } } if (fieldNames.size() < 2) { JOptionPane.showMessageDialog(null, "This example needs a feature type with at least two String fields", "Bummer", JOptionPane.WARNING_MESSAGE); return null; } Style style = null; FieldWizard wizard = new FieldWizard(fieldNames); if (wizard.showModalDialog() == JWizard.FINISH) { String[] fields = wizard.getSelections(); style = SLD.createSimpleStyle((SimpleFeatureType) schema, Color.CYAN); StyleFactory sf = CommonFactoryFinder.getStyleFactory(null); FilterFactory ff = CommonFactoryFinder.getFilterFactory2(null); TextSymbolizer sym = sf.createTextSymbolizer(); /* * Instead of setting the label to a feature property directly, * we set it to a filter function ("concatenate") to form a * compound label from two properties and a delimiter */ sym.setLabel(ff.function("Concatenate", ff.property(fields[0]), ff.literal(":"), ff.property(fields[1]))); SLD.rules(style)[0].symbolizers().add(sym); return style; } return style; } /** * A JWizard to prompt the user for the feature attributes to use * for labelling */ class FieldWizard extends JWizard { JComboBox field1CB; JComboBox field2CB; public FieldWizard(final List<String> items) { super("Fields for labels"); JPage page = new JPage() { @Override public JPanel createPanel() { JPanel panel = super.createPanel(); panel.setLayout(new MigLayout()); JLabel label1 = new JLabel("First label part"); panel.add(label1, "wrap"); field1CB = new JComboBox(items.toArray()); field1CB.setEditable(false); field1CB.addActionListener(this.getJWizard().getController()); panel.add(field1CB, "gapbefore indent, wrap"); JLabel label2 = new JLabel("Second label part"); panel.add(label2, "wrap"); field2CB = new JComboBox(items.toArray()); field2CB.setEditable(false); field2CB.addActionListener(this.getJWizard().getController()); panel.add(field2CB, "gapbefore indent, wrap"); return panel; } @Override public boolean isValid() { String field1 = (String) field1CB.getSelectedItem(); String field2 = (String) field2CB.getSelectedItem(); if (field1.equals(field2)) { return false; } return true; } }; page.setPageIdentifier(JPage.DEFAULT); this.registerWizardPanel(page); } public String[] getSelections() { String[] selections = new String[2]; selections[0] = (String) field1CB.getSelectedItem(); selections[1] = (String) field2CB.getSelectedItem(); return selections; } } }