30 June 2006

Here I post a sample java class I developed some months ago, working with geometry creation in GeoTools 2. This class, given an input shapefile, will elaborate an output shapefile merging the input polygons on a common field.

Geotools is an open source (LGPL) Java code library which provides standards compliant methods for the manipulation of geospatial data, for example to implement Geographic Information Systems (GIS). The Geotools library implements Open Geospatial Consortium (OGC) specifications as they are developed, in close collaboration with the GeoAPI and GeoWidgets projects. The capabilities of Geotools are presented in the feature list.
 * Created on 24-giu-2004
package com.PaoloCorti.GIS.GeometryBuilder;

 * @author corti
 * Richiede GeoTools2 e jts 1.4.0
 * Effettua il merge dei poligoni di uno shapefile in input sulla base di un campo, restituendo uno shapefile in output
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureReader;
import org.geotools.data.FeatureResults;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.geotools.data.Transaction;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.dbf.DbaseFileReader;
import org.geotools.feature.AttributeType;
import org.geotools.feature.AttributeTypeFactory;
import org.geotools.feature.Feature;
import org.geotools.feature.FeatureType;
import org.geotools.feature.FeatureTypeFactory;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.filter.AttributeExpression;
import org.geotools.filter.CompareFilter;
import org.geotools.filter.FilterFactory;
import org.geotools.filter.FilterType;
import org.geotools.filter.LiteralExpression;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.MultiPolygon;

public class UnionPolygonByAttribute {

  * main, richiede come parametri:
  * 1. shapefile di input (es: C:\temp\datiGIS\province.shp)
  * 2. campo sul quale effettuare il merge (es: c:\temp\datiGIS\output.shp)
  * 3. shapefile di output (es: COD_REG)
  * Es per lanciarlo da linea di comando:
  * java -classpath C:/java/geotools/jars/gt2-main.jar;C:/java/geotools/jars/gt2-shapefile.jar;C:/java/geotools/lib/JTS-1.4.jar; com.PaoloCorti.GIS.GeometryBuilder.UnionPolygonByAttribute "file:/C:/temp/datiGIS/province" "COD_REG" "file:/C:/temp/datiGIS/output"
  * @param args
  * @throws Exception
      public static void main(String[] args) throws Exception  {
                  String inputShape = args[0];
                  String fieldToUnionName = args[1];
                  String outputShape = args[2];
                  String inDBFName = inputShape.substring(6, inputShape.length()) + ".dbf";
                  Stampa("processo lo shape " + inputShape + " nello shape " + outputShape + " unendo le feature con lo stesso " + fieldToUnionName);
                  UnionPolyByField(inputShape, outputShape, fieldToUnionName, inDBFName);
               Stampa("specificare tutti i parametri!");

       * Effettua il merge dello shape di input in uno shape di output
       * @param InputShape Shapefile di input (da mergiare)
       * @param OutputShape Shapefile di output (mergiato)
       * @param FieldToUnionName Campo sul quale effettuare il merge nello shapefile di input
       * @param InDBFName Nome tabella DBF
       * @throws Exception
      private static void UnionPolyByField(String InputShape, String OutputShape, String FieldToUnionName, String InDBFName) throws Exception
            FileChannel in = new FileInputStream(InDBFName).getChannel();
                         DbaseFileReader r = new DbaseFileReader(in);
                         int fields = r.getHeader().getNumFields();
                         int recordCount = r.getHeader().getNumRecords();
                         int fieldToUnionIndex=0;
                         Class fieldType = null;
                         for (int i=0; i<fields; i++){
                             String fieldName = r.getHeader().getFieldName(i);
                                   fieldToUnionIndex = i;
                                   //leggiamo il datatype
                                   fieldType = r.getHeader().getFieldClass(i);
                         Stampa("tipo campo: " + fieldType.toString());
                         String fieldUniqueValueArr[] = new String[recordCount];
                         int j = 0;
                         while (r.hasNext()) {
                             DbaseFileReader.Row row = r.readRow();
                             //make array
                         //shape da leggere e interrogare (input)
                         ShapefileDataStore sds = new ShapefileDataStore(new URL(InputShape));
                         String name = sds.getTypeNames()[0];  //solo 1 parametro per gli shape
                         Stampa("DATASTORE.getTypeNames() = " + name);
                         //leggo le feature
                         FeatureSource fs = sds.getFeatureSource(name);
                         FeatureType featureType = fs.getSchema();
                         FeatureResults fres = fs.getFeatures();
                         Stampa(fres.getCount() + " features nello shapefile");
                         //creiamo lo shapefile
                         ShapefileDataStore newShapeFileDatastore = new ShapefileDataStore(new URL(OutputShape));
                         //creiamo lo schema dello shape
                         AttributeType attUnionGeom = AttributeTypeFactory.newAttributeType("the_geom", MultiPolygon.class);
                         AttributeType attArea = AttributeTypeFactory.newAttributeType("AREA", Double.class);
                         AttributeType attPerimeter = AttributeTypeFactory.newAttributeType("PERIMETER", Double.class);
                         FeatureType newFeatureType = FeatureTypeFactory.newFeatureType(new AttributeType[] {attUnionGeom, attArea, attPerimeter}, name);
                         FeatureSource newFeatureSource = newShapeFileDatastore.getFeatureSource(name);
                         FeatureStore newFeatureStore = (FeatureStore)newFeatureSource;
                         //sort array
                         String oldValue = fieldUniqueValueArr[0];
                         for(int i=0; i<fieldUniqueValueArr.length; i++){
                           if(!fieldUniqueValueArr.equalsIgnoreCase(oldValue) || i==0){
                                oldValue = fieldUniqueValueArr;
                                //faccio il filtro
                                    FilterFactory ff = FilterFactory.createFilterFactory();
                                    CompareFilter cf = ff.createCompareFilter(FilterType.COMPARE_EQUALS);
                                    AttributeExpression attExpression = ff.createAttributeExpression(featureType, FieldToUnionName);
                                    LiteralExpression l1;
                                    l1 = ff.createLiteralExpression(Double.parseDouble(oldValue)); //qui va modificato a seconda del datatype
                                    //faccio la query
                                    FeatureResults fQueryResults = fs.getFeatures(cf);
                                    int numFeat = fQueryResults.getCount();
                                    Stampa(numFeat + " features con " + FieldToUnionName + " = " + oldValue);
                                    //leggiamo le feature ottenute
                                    FeatureReader featureReader = fQueryResults.reader();
                                    Transaction t = newFeatureStore.getTransaction();
                                    //aggiungiamo le feature
                                    Geometry polyUnion = PolygonUnion(featureReader, numFeat);
                                    if(polyUnion instanceof MultiPolygon)
                                          Double area = new Double(polyUnion.getArea());
                                          Double perimeter = new Double(polyUnion.getLength());
                                          Feature f = newFeatureType.create(new Object[] {polyUnion, area, perimeter});
                                          FeatureReader newFeatureReader = DataUtilities.reader(new Feature[] {f});

       * Unisce n poligoni in un poligono
       * @param fr
       * @param nfeat
       * @return
      private static Geometry PolygonUnion(FeatureReader fr, int nfeat) {
            try {
                             //array Geometry jts
                             int i=0;
                             Geometry geomarr[] = new Geometry[nfeat];
                          while(fr.hasNext()) {
                               Feature feature = fr.next();
                               geomarr[i++] = feature.getDefaultGeometry();
                             //System.out.print(i + "/" + nfeat + "-");
                             //ora faccio buffer
                             Geometry geom = geomarr[0];
                             for (i=0; i<nfeat; i++) {
                                   geom = geom.union(geomarr);
                             Stampa("CREATO POLIGONO!");
                             return geom;
            catch(IllegalAttributeException error){
                  Stampa("errore geometrico!");
                  return null;            
            catch(IOException error){
                  Stampa("errore geometrico!");
                  return null;            

      private static void Stampa(String stringa){

blog comments powered by Disqus