[metacat-cvs] metacat/src/edu/ucsb/nceas/metacat/spatial SldFactory.java SpatialDataset.java SpatialDocument.java SpatialFeatureSchema.java SpatialHarvester.java WmsFilter.java

Mathew Perry perry at ecoinformatics.org
Thu Aug 31 16:54:32 PDT 2006


perry       06/08/31 16:54:32

  Added:       src/edu/ucsb/nceas/metacat/spatial SldFactory.java
                        SpatialDataset.java SpatialDocument.java
                        SpatialFeatureSchema.java SpatialHarvester.java
                        WmsFilter.java
  Log:
  refactory java classes for spatial harvester
  
  Revision  Changes    Path
  1.1                  metacat/src/edu/ucsb/nceas/metacat/spatial/SldFactory.java
  
  Index: SldFactory.java
  ===================================================================
  /*
   * Styled Layer Descriptor Factory
   * Author: Matt Perry
   * Status: testing
   * MPTODO: Use a spatial access constraints class to generate the appropriate SLD filter
   */
  package edu.ucsb.nceas.metacat.spatial;
  
  import edu.ucsb.nceas.utilities.XMLUtilities;
  
  import javax.servlet.ServletConfig;
  import javax.servlet.ServletContext;
  import javax.servlet.ServletException;
  import javax.servlet.ServletInputStream;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpSession;
  import javax.servlet.http.HttpUtils;
  import javax.servlet.ServletOutputStream;
  
  import javax.xml.parsers.DocumentBuilder; 
  import javax.xml.parsers.DocumentBuilderFactory;  
  import javax.xml.parsers.FactoryConfigurationError;  
  import javax.xml.parsers.ParserConfigurationException;
  
  import org.xml.sax.SAXException;  
  import org.xml.sax.SAXParseException;
  
  import java.io.File;
  import java.io.IOException;
  
  import org.w3c.dom.*;
  
  public class SldFactory extends HttpServlet {
    
    static Document document;
    static String sld;
    
    /** Handle "GET" method requests from HTTP clients */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
      handleGetOrPost(request, response);
    }
  
    /** Handle "POST" method requests from HTTP clients */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
      handleGetOrPost(request, response);
    }
  
    /**
     * Control servlet response depending on the action parameter specified
     */
    private void handleGetOrPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException
    {
      //String dataset = request.getParameter("dataset"); 
      // MPTODO : Eventually use dataset to determine filename
      String filename = "/var/lib/tomcat5/webapps/knb/style/skins/ebm/spatial/data_bounds_style.sld";
      String sld = getSld(filename);
      
      response.setContentType("text/xml");
      response.getWriter().write(sld);
      
      System.out.println("\n*** SldFactory request handled ***\n");
    }
    
    /**
     * Given a filename of an existing SLD document,
     * reads the sld and adds an ogc:Filter to exclude/include
     * certain docids based on user's permissions. 
     * 
     * returns SLD document as a String.
     * 
     * @param filename	Filename of the base sld.
     * 
     */
    private String getSld(String filename)
    {
  	    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  
  	    try {
  	       DocumentBuilder builder = factory.newDocumentBuilder();
  	       document = builder.parse( new File(filename) );	       
  	    } catch (SAXException sxe) {
  	       sxe.printStackTrace();
  	    } catch (ParserConfigurationException pce) {
  	       pce.printStackTrace();
  	    } catch (IOException ioe) {
  	       ioe.printStackTrace();
  	    }
  	    
  	    Element root = document.getDocumentElement();
  	    NodeList elemList = document.getElementsByTagName("Rule");
  	    Node ruleNode = elemList.item(0);
  	    
  	    // Get the list of docids  due to access contrainsts
  	    
  	    // Get the list of docids  due to skin filtering of org names
  	    
  	    // Get the list of docids  due to existing query (eg taxonomic)
  	    
  	    // Get the Element/node comprising the ogc:Filter for all of the above
  	    Element filterElement = getFilterElement(document);
  	    
  	    // Append the Filter to the ruleNode
  	    ruleNode.appendChild(filterElement);
  	    
  	    // Write new DOM as a string
  	    String rulesString = XMLUtilities.getDOMTreeAsString((Node) root, true);
  
  	    return rulesString;
    }
  
    /**
     * Given a DOM document and a vector of docids,
     * Creates an OGC Filter node
     * 
     * @param inDoc	DOM document.
     * 
     */
    private Element getFilterElement(Document inDoc) 
    {
  	  Element filterElem = inDoc.createElement("ogc:Filter");
  	  
  	  // MPTODO : BEGIN LOOP thru vector of docids
  	  Element opElem = inDoc.createElement("ogc:PropertyIsEqualTo");
  	  
  	  Element propertyElem = inDoc.createElement("ogc:PropertyName");
  	  Text propertyText = inDoc.createTextNode("docid");
  	  propertyElem.appendChild(propertyText);
  	  
  	  Element literalElem = inDoc.createElement("ogc:Literal");	  
  	  Text literalText = inDoc.createTextNode("perry.1"); // i
  	  literalElem.appendChild(literalText);
  	  
  	  opElem.appendChild(propertyElem);
  	  opElem.appendChild(literalElem);
  	  filterElem.appendChild(opElem);
  	  // END LOOP
  	  
  	  return filterElem;	  
    }
    
  }
  
  
  
  1.1                  metacat/src/edu/ucsb/nceas/metacat/spatial/SpatialDataset.java
  
  Index: SpatialDataset.java
  ===================================================================
  /**
   *  '$RCSfile: SpatialDataset.java,v $'
   *  Copyright: 2003 Regents of the University of California.
   *
   * Author: Matthew Perry 
   * '$Date: 2006/08/31 23:54:31 $'
   * '$Revision: 1.1 $'
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  package edu.ucsb.nceas.metacat.spatial;
  
  import org.geotools.feature.FeatureType;
  import org.geotools.data.shapefile.ShapefileDataStore;
  import org.geotools.data.FeatureStore;
  import org.geotools.data.DefaultTransaction;
  import org.geotools.data.Transaction;
  import org.geotools.feature.Feature;
  import org.geotools.filter.Filter;
  import org.geotools.filter.CompareFilter;
  import org.geotools.filter.FilterFactory;
  import org.geotools.filter.FilterFactoryFinder;
  import org.geotools.filter.IllegalFilterException;
  import org.geotools.feature.FeatureCollection;
  import org.geotools.feature.FeatureCollections;
  
  import org.apache.log4j.Logger;
  
  import java.io.File;
  import java.io.IOException;
  
  import java.net.URI;
  import java.net.URL;
  import java.net.MalformedURLException;
  
  import edu.ucsb.nceas.metacat.MetaCatUtil;
  
  
  public class SpatialDataset {
  
    SpatialFeatureSchema featureSchema = new SpatialFeatureSchema();
  
    //public String polygonShpUri = MetaCatUtil.getOption("certPath") + "data/metacat_shps/data_bounds.shp";
    //public String pointShpUri = MetaCatUtil.getOption("certPath")+ "data/metacat_shps/data_points.shp";
  
    FeatureCollection polygonCollection = FeatureCollections.newCollection();
    FeatureCollection pointCollection = FeatureCollections.newCollection();
  
    private static Logger log =
        Logger.getLogger(SpatialDataset.class.getName());
  
    /** empty constructor **/
    public SpatialDataset() {
      
    }
  
    /*
     * Adds a new feature (from a SpatialDocument)
     * This is faster than insertOrUpdate but 
     * relying on this method might cause duplication
     * of docids in the spatial cache. Therefore, its really only useful when 
     * regenerating the entire cache.
     */ 
    public void add( String geomType, Feature feature ) {
       if( geomType.equals("polygon") ) {
           // Check if feature actually is a multipolygon
           if( feature != null) 
               polygonCollection.add( feature );
           
       } else if( geomType.equals("point") ) {
           // Check if feature actually is a multipoint
           if( feature != null) 
               pointCollection.add( feature );
       }
    }
  
    /*
     * Deletes given docid from the spatial cache.
     */
    public void delete( String geomType, String docid ) throws IOException {
  
      FilterFactory filterFactory = FilterFactoryFinder.createFilterFactory();
      CompareFilter filter = null;
      FeatureStore fStore = null;
      ShapefileDataStore dStore = null;
  
      try {
          // Create the filter
          filter = filterFactory.createCompareFilter(CompareFilter.COMPARE_EQUALS);
          filter.addLeftValue(filterFactory.createAttributeExpression("docid"));
          filter.addRightValue(filterFactory.createLiteralExpression(docid));
      } catch (IllegalFilterException e) {
          e.printStackTrace();
      }
  
      // Begin new transaction
      Transaction t = new DefaultTransaction("handle");
      t.putProperty( "updating spatial cache", new Integer(7) );
      String lockId = "SpatialDataset.delete";
      
      try {
          
          boolean validGeomType = false;
  
          if( geomType.equals("polygon") ) {
              dStore = new ShapefileDataStore( (new File( featureSchema.polygonShpUri )).toURL() );
              fStore = (FeatureStore) dStore.getFeatureSource(dStore.getTypeNames()[0]);
              validGeomType = true;
          } else if( geomType.equals("point") ) {
              dStore = new ShapefileDataStore( (new File( featureSchema.pointShpUri )).toURL() );
              fStore = (FeatureStore) dStore.getFeatureSource(dStore.getTypeNames()[0]);
              validGeomType = true;
          }
  
          // Initiate the transaction
          fStore.setTransaction( t );
          t.addAuthorization( lockId );
          
          if( validGeomType == true) {
              // Remove old feature
              fStore.removeFeatures( filter );
  
              // Commit changes to shapefile
              t.commit();
              log.info(" Delete docid " + docid + " from spatial cache");
          }
  
      } catch (MalformedURLException e) {
          e.printStackTrace();
          t.rollback(); // cancel opperations
      } catch (IOException e) {
          e.printStackTrace();
          t.rollback(); // cancel opperations
      } finally {
          // Close out the transaction
          t.close();
      }
  
    }
  
    /*
     * Either inserts or updates the spatial cache with the new
     * spatial document depending on if it currently exists.
     * Docid is also passed in for quicker searching.
     */
    public void insertOrUpdate( String geomType, Feature feature, String docid ) throws IOException {
      
      FeatureCollection fColl = FeatureCollections.newCollection();
      FilterFactory filterFactory = FilterFactoryFinder.createFilterFactory();
      CompareFilter filter = null;
      FeatureStore fStore = null;
      ShapefileDataStore dStore = null;
  
      // Explain why geotools fails to create the projection info from the shapefile
      log.info( " The '.prj' errors below are related to a geotools bug " +
                " (http://jira.codehaus.org/browse/GEOT-604) and can be ignored");
  
      try {
          // Create the filter
          filter = filterFactory.createCompareFilter(CompareFilter.COMPARE_EQUALS);
          filter.addLeftValue(filterFactory.createAttributeExpression("docid"));
          filter.addRightValue(filterFactory.createLiteralExpression(docid));
      } catch (IllegalFilterException e) {
          e.printStackTrace();
      }
  
      // Begin new transaction
      Transaction t = new DefaultTransaction("handle");
      t.putProperty( "updating spatial cache", new Integer(7) );
      String lockId = "SpatialDataset.insertOrUpdate";
      
      try {
          
          boolean validGeomType = false;
  
          if( geomType.equals("polygon") ) {
              dStore = new ShapefileDataStore( (new File( featureSchema.polygonShpUri )).toURL() );
              fStore = (FeatureStore) dStore.getFeatureSource(dStore.getTypeNames()[0]);
              validGeomType = true;
          } else if( geomType.equals("point") ) {
              dStore = new ShapefileDataStore( (new File( featureSchema.pointShpUri )).toURL() );
              fStore = (FeatureStore) dStore.getFeatureSource(dStore.getTypeNames()[0]);
              validGeomType = true;
          }
  
          // Initiate the transaction
          fStore.setTransaction( t );
          t.addAuthorization( lockId );
          
          if( feature != null && validGeomType == true) {
              // Remove old feature
              fStore.removeFeatures( filter );
  
              // Create new feature collection then add it to feature Store
              fColl.add( feature );
              fStore.addFeatures(fColl);
  
              // Commit changes to shapefile
              t.commit();
              log.info(" Insert or Update docid " + docid + " from spatial cache");
          }
  
  
      } catch (MalformedURLException e) {
          e.printStackTrace();
          t.rollback(); // cancel opperations
      } catch (IOException e) {
          e.printStackTrace();
          t.rollback(); // cancel opperations
      } finally {
          // Close out the transaction
          t.close();
      }
  
  
    }
  
    /*
     * Saves the SpatialDataset object to the spatial cache
     */
    public void save() {
           // Save Polygons 
           try {
               URL anURL = (new File( featureSchema.polygonShpUri )).toURL();
               ShapefileDataStore polygonDatastore = new ShapefileDataStore(anURL);
               FeatureType polygonType = featureSchema.getPolygonFeatureType();
               polygonDatastore.createSchema( polygonType );
               FeatureStore polygonFeatureStore = (FeatureStore) polygonDatastore.getFeatureSource( polygonType.getTypeName() );
               polygonFeatureStore.addFeatures( polygonCollection );
               log.info(" ---- Polygons saved to " + featureSchema.polygonShpUri );
           } catch(java.net.MalformedURLException e) {
               log.error("Malformed URL Exception : "+e);
           } catch(java.io.IOException e) {
               log.error("IO Exception : "+e);
  
           }
  
           // Save Points
           try {
               URL anURL = (new File( featureSchema.pointShpUri )).toURL();
               ShapefileDataStore pointDatastore = new ShapefileDataStore(anURL);
               FeatureType pointsType = featureSchema.getPointFeatureType();
               pointDatastore.createSchema( pointsType );
               FeatureStore pointFeatureStore = (FeatureStore) pointDatastore.getFeatureSource( pointsType.getTypeName() );
               pointFeatureStore.addFeatures( pointCollection );
               log.info(" ---- Polygons saved to " + featureSchema.pointShpUri );
           } catch(java.net.MalformedURLException e) {
               log.error("Malformed URL Exception : "+e);
           } catch(java.io.IOException e) {
               log.error("IO Exception : "+e);
           }
    }
  
  }
  
  
  
  1.1                  metacat/src/edu/ucsb/nceas/metacat/spatial/SpatialDocument.java
  
  Index: SpatialDocument.java
  ===================================================================
  /**
   *  '$RCSfile: SpatialDocument.java,v $'
   *  Copyright: 2003 Regents of the University of California.
   *
   * Author: Matthew Perry 
   * '$Date: 2006/08/31 23:54:32 $'
   * '$Revision: 1.1 $'
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  package edu.ucsb.nceas.metacat.spatial;
  
  import java.io.File;
  
  import edu.ucsb.nceas.metacat.DBConnection;
  import edu.ucsb.nceas.metacat.MetaCatUtil;
  
  import com.vividsolutions.jts.geom.Coordinate;
  import com.vividsolutions.jts.geom.Point;
  import com.vividsolutions.jts.geom.Polygon;
  import com.vividsolutions.jts.geom.MultiPolygon;
  import com.vividsolutions.jts.geom.MultiPoint;
  import com.vividsolutions.jts.geom.GeometryFactory;
  import com.vividsolutions.jts.geom.PrecisionModel;
  
  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.SchemaException;
  
  import java.sql.ResultSet;
  import java.sql.PreparedStatement;
  import java.util.Vector;
  
  import org.apache.log4j.Logger;
  
  public class SpatialDocument {
  
    private DBConnection dbconn;
  
    private static Logger log =
        Logger.getLogger(SpatialDocument.class.getName());
  
    private SpatialFeatureSchema featureSchema = new SpatialFeatureSchema();
  
    Vector west = new Vector();
    Vector south = new Vector();
    Vector east = new Vector();
    Vector north = new Vector();
  
    String title = null;
    String docid = null;
  
    /** constructor that queries the db **/
    public SpatialDocument( String docid , DBConnection dbconn ) {
  
      this.docid = docid;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      this.dbconn = dbconn;
  
      /*
       * Get the bounding coordinates
       */
      String query = "SELECT path, nodedatanumerical, parentnodeid FROM xml_path_index"
      + " WHERE docid = '" + docid.trim() + "'"
      + " AND (path = '" + MetaCatUtil.getOption("westBoundingCoordinatePath") + "'"
      + "  OR path = '" + MetaCatUtil.getOption("southBoundingCoordinatePath") + "'"
      + "  OR path = '" + MetaCatUtil.getOption("eastBoundingCoordinatePath") + "'"
      + "  OR path = '" + MetaCatUtil.getOption("northBoundingCoordinatePath") + "'"
      + " ) ORDER BY parentnodeid;";
  
      try {
        pstmt = dbconn.prepareStatement(query);
        pstmt.execute();
        rs = pstmt.getResultSet();
        while (rs.next()) {
          if ( rs.getString(1).equals( MetaCatUtil.getOption("westBoundingCoordinatePath") ) )
              this.west.add( rs.getFloat(2) );
          else if ( rs.getString(1).equals( MetaCatUtil.getOption("southBoundingCoordinatePath") ) )
              this.south.add( rs.getFloat(2) );
          else if ( rs.getString(1).equals( MetaCatUtil.getOption("eastBoundingCoordinatePath") ) )
              this.east.add( rs.getFloat(2) );
          else if ( rs.getString(1).equals( MetaCatUtil.getOption("northBoundingCoordinatePath") ) )
              this.north.add( rs.getFloat(2) );
          else
              log.error("** An xml path not related to your bounding coordinates was returned by this query \n" + query + "\n");
        }
        rs.close();
        pstmt.close();
      }
      catch(Exception e) {
        log.error(" ---- Error getting bounding coordinates for " + docid);
        e.printStackTrace();
      }      
  
      // Get the Title
      query = "select docid, nodedata, nodeid "
            + "from xml_nodes "
            + "where parentnodeid = "
            + "  ( select  nodeid "
            + "    from  xml_nodes "
            + "    where docid like '" + docid.trim() +"' "
            + "    and nodename like 'title%' "
            + "    and parentnodeid = "
            + "      ( select nodeid "
            + "        from xml_nodes "
            + "        where docid like '" + docid.trim() + "' "
            + "        and nodename = 'dataset' "
            + "        limit 1) "
            + "    limit 1)" ;
  
      try {
        pstmt = dbconn.prepareStatement(query);
        pstmt.execute();
        rs = pstmt.getResultSet();
        if (rs.next())
          this.title = rs.getString(2);
        rs.close();
        pstmt.close();
      }
      catch(Exception e) {
        log.error(" **** Error getting docids from getTitle for docid = "+docid);
        e.printStackTrace();
        log.error(" query ============== \n " + query);
        this.title = docid;
      }
  
      /* try {
          dbconn.close();
      } catch( java.sql.SQLException e ) {
          log.error("java.sql.SQLException");
      }
      */
  
    }
  
    /* 
     * Returns a jts (multi)polygon feature with geometry plus attributes
     * ready to be inserted into our spatial dataset cache
     */
    public Feature getPolygonFeature() {
        // Get polygon feature type
        FeatureType polyType = featureSchema.getPolygonFeatureType();
  
        MultiPolygon theGeom = getPolygonGeometry();
        if (theGeom == null)
            return null;
  
        // Populate the feature schema
        try {
            Feature polyFeature = polyType.create(new Object[]{ 
                theGeom,
                this.docid,
                getUrl(this.docid), 
                this.title });
            return polyFeature; 
        } catch (org.geotools.feature.IllegalAttributeException e) {
            log.error("!!!!!!! org.geotools.feature.IllegalAttributeException");
            return null;
        }
    }
  
    /* 
     * Returns a jts (multi)point feature with geometry plus attributes
     * ready to be inserted into our spatial dataset cache
     */
    public Feature getPointFeature() {
        // Get polygon feature type
        FeatureType pointType = featureSchema.getPointFeatureType();
  
        MultiPoint theGeom = getPointGeometry();
        if (theGeom == null)
            return null;
  
        // Populate the feature schema
        try {
            Feature pointFeature = pointType.create(new Object[]{ 
                theGeom,
                this.docid,
                getUrl(this.docid), 
                this.title });
            return pointFeature;
        } catch (org.geotools.feature.IllegalAttributeException e) {
            log.error("!!!!!!! org.geotools.feature.IllegalAttributeException");
            return null;
        }
    }
  
    /*
     * Given a valid docid, return an appropriate URL
     * for viewing the metadata document
     */
    private String getUrl( String docid ) {
       String docUrl = MetaCatUtil.getOption("metacatUrl")  
                      + "?action=read"
                      + "&docid=" + docid 
                      + "&qformat=" + MetaCatUtil.getOption("default-style");
  
       return docUrl;
    }
  
    /**
     * returns the title of the docid
     */
    private String getTitle(String docid) {
      String title = null;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      String query = "select docid, nodedata, nodeid "
                   + "from xml_nodes "
                   + "where parentnodeid = "
                   + "  ( select  nodeid "
                   + "    from  xml_nodes "
                   + "    where docid like '" + docid.trim() +"' "
                   + "    and nodename like 'title%' "
                   + "    and parentnodeid = "
                   + "      ( select nodeid "
                   + "        from xml_nodes "
                   + "        where docid like '" + docid.trim() + "' "
                   + "        and nodename = 'dataset' "
                   + "        limit 1) "
                   + "    limit 1)" ;
  
      /*
       * String query = "select docid, nodedata, nodeid from xml_nodes where "
       *   + "nodeid =(select  nodeid from  xml_nodes where docid  like '"
       *   + docid.trim() + "' and nodename like 'title%');";
       */
  
      try {
        dbconn = new DBConnection();
        pstmt = dbconn.prepareStatement(query);
        pstmt.execute();
        rs = pstmt.getResultSet();
        if (rs.next())
          title = rs.getString(2);
        rs.close();
        pstmt.close();
        dbconn.close();
      }
      catch(Exception e) {
        log.error(" **** Error getting docids from getTitle for docid = "+docid);
        e.printStackTrace();
        log.error(" query ============== \n " + query);
        title = docid;
      }
      
      return title;
    }
  
  
    /*
     * Returns polygon geometry
     */
    private MultiPolygon getPolygonGeometry() {
  
      PrecisionModel precModel = new PrecisionModel(); // default: Floating point
      GeometryFactory geomFac = new GeometryFactory( precModel, featureSchema.srid );
  
      Vector polygons = new Vector();
  
      if ( west.size() == south.size() && south.size() == east.size() && east.size() == north.size() ) {
          for (int i = 0; i < west.size(); i++) {
  
              Coordinate[] linestringCoordinates = new Coordinate[5];
  
              // Check if it's actually a valid polygon
              if ( (Float)west.elementAt(i) == 0.0 &&
                   (Float)east.elementAt(i) == 0.0 && 
                   (Float)north.elementAt(i) == 0.0 &&
                   (Float)south.elementAt(i) == 0.0) {
  
                  log.warn("        Invalid or empty coodinates ... skipping");
                  continue;
              } else if( ((Float)west.elementAt(i)).compareTo( (Float)east.elementAt(i) ) == 0 && 
                         ((Float)north.elementAt(i)).compareTo( (Float)south.elementAt(i) ) == 0 ) {
  
                  log.warn("        Point coordinates only.. skipping polygon generation");
                  continue;
              }
  
              linestringCoordinates[0] = new Coordinate( (Float)west.elementAt(i), (Float)south.elementAt(i) );
              linestringCoordinates[1] = new Coordinate( (Float)west.elementAt(i), (Float)north.elementAt(i));
              linestringCoordinates[2] = new Coordinate( (Float)east.elementAt(i), (Float)north.elementAt(i));
              linestringCoordinates[3] = new Coordinate( (Float)east.elementAt(i), (Float)south.elementAt(i));
              linestringCoordinates[4] = new Coordinate( (Float)west.elementAt(i), (Float)south.elementAt(i));
              polygons.add( geomFac.createPolygon( geomFac.createLinearRing(linestringCoordinates), null) );
          }
      } else {
         log.error(" *** Something went wrong.. your east,west,north and south bounding arrays are different sizes!");
      }
      
      if( polygons.size() > 0 ) {
         Polygon[] polyArray = geomFac.toPolygonArray( polygons );
         MultiPolygon multiPolyGeom= geomFac.createMultiPolygon( polyArray );
         return multiPolyGeom; 
      } else {
         return null;
      } 
  
    }
     
    /*
     * returns a point geometry
     */
    private MultiPoint getPointGeometry() {
  
      PrecisionModel precModel = new PrecisionModel(); // default: Floating point
      GeometryFactory geomFac = new GeometryFactory( precModel, featureSchema.srid );
  
      PreparedStatement pstmt = null;
      ResultSet rs = null;
  
      Vector points = new Vector();
  
      if ( west.size() == south.size() && south.size() == east.size() && east.size() == north.size() ) {
          for (int i = 0; i < west.size(); i++) {
  
              // Check if it's actually a valid point
              if ( (Float)west.elementAt(i) == (float)0.0 &&
                   (Float)east.elementAt(i) == (float)0.0 && 
                   (Float)north.elementAt(i) == (float)0.0 &&
                   (Float)south.elementAt(i) == (float)0.0 ) {
  
                  log.warn("        Invalid or empty coodinates ... skipping");
                  continue;
              }
  
              Double xCenter = ( (Float)west.elementAt(i) + (Float)east.elementAt(i) ) / (Double) 2.0;
              Double yCenter = ( (Float)south.elementAt(i) + (Float)north.elementAt(i) ) / (Double) 2.0;
              points.add( geomFac.createPoint( new Coordinate( xCenter, yCenter)) );
          }
      } else {
         log.error(" *** Something went wrong.. your east,west,north and south bounding vectors are different sizes!");
      }
      
      if( points.size() > 0 ) {
         Point[] pointArray = geomFac.toPointArray( points );
         MultiPoint multiPointGeom= geomFac.createMultiPoint( pointArray );
         return multiPointGeom; 
      } else {
         return null;
      } 
  
  
    }
  }
  
  
  
  1.1                  metacat/src/edu/ucsb/nceas/metacat/spatial/SpatialFeatureSchema.java
  
  Index: SpatialFeatureSchema.java
  ===================================================================
  /**
   *  '$RCSfile: SpatialFeatureSchema.java,v $'
   *  Copyright: 2003 Regents of the University of California.
   *
   * Author: Matthew Perry 
   * '$Date: 2006/08/31 23:54:32 $'
   * '$Revision: 1.1 $'
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  package edu.ucsb.nceas.metacat.spatial;
  
  import edu.ucsb.nceas.metacat.MetaCatUtil;
  
  import com.vividsolutions.jts.geom.MultiPolygon;
  import com.vividsolutions.jts.geom.MultiPoint;
  import org.geotools.feature.AttributeType;
  import org.geotools.feature.AttributeTypeFactory;
  import org.geotools.feature.FeatureType;
  import org.geotools.feature.FeatureTypeFactory;
  import org.geotools.feature.SchemaException;
  
  import org.apache.log4j.Logger;
  
  
  public class SpatialFeatureSchema {
  
    private static Logger log =
        Logger.getLogger(SpatialFeatureSchema.class.getName());
  
    public static String polygonShpUri = MetaCatUtil.getOption("certPath") + "data/metacat_shps/data_bounds.shp";
    public static String pointShpUri = MetaCatUtil.getOption("certPath")+ "data/metacat_shps/data_points.shp";
  
    // EPSG for latlong coordinate system w/ WGS84 datum
    public static int srid = 4326;
  
    /** empty constructor **/
    public SpatialFeatureSchema() {
           
    }
  
    /*
     * Creates the featuretype schema for polygon bounds
     */
    public static FeatureType getPolygonFeatureType() {
      try {
          AttributeType[] types = new AttributeType[4];
          types[0] = AttributeTypeFactory.newAttributeType("the_geom", com.vividsolutions.jts.geom.MultiPolygon.class);
          types[1] = AttributeTypeFactory.newAttributeType("docid", String.class);
          types[2] = AttributeTypeFactory.newAttributeType("url", String.class);
          types[3] = AttributeTypeFactory.newAttributeType("title", String.class);
          FeatureType boundsType = FeatureTypeFactory.newFeatureType(types, "bounds");
          return boundsType;
      } catch(SchemaException e) {
          log.error("schema exception : "+e);
          return null;
      }
    }
  
    /*
     * Creates the featuretype schema for point centroids
     */
    public static FeatureType getPointFeatureType() {
      try {
          AttributeType[] types = new AttributeType[4];
          types[0] = AttributeTypeFactory.newAttributeType("the_geom", com.vividsolutions.jts.geom.MultiPoint.class);
          types[1] = AttributeTypeFactory.newAttributeType("docid", String.class);
          types[2] = AttributeTypeFactory.newAttributeType("url", String.class);
          types[3] = AttributeTypeFactory.newAttributeType("title", String.class);
          FeatureType centroidsType = FeatureTypeFactory.newFeatureType(types, "centroids");
          return centroidsType;
      } catch(SchemaException e) {
          log.error("schema exception : "+e);
          return null;
      }
    }
  
  }
  
  
  
  1.1                  metacat/src/edu/ucsb/nceas/metacat/spatial/SpatialHarvester.java
  
  Index: SpatialHarvester.java
  ===================================================================
  /**
   *  '$RCSfile: SpatialHarvester.java,v $'
   *  Copyright: 2000 Regents of the University of California and the
   *             National Center for Ecological Analysis and Synthesis
   *
   * Author: Matthew Perry 
   * '$Date: 2006/08/31 23:54:32 $'
   * '$Revision: 1.1 $'
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  
  package edu.ucsb.nceas.metacat.spatial;
  
  import java.sql.ResultSet;
  import java.sql.PreparedStatement;
  import java.util.Vector;
  import java.io.IOException;
  
  import org.apache.log4j.Logger;
  
  import edu.ucsb.nceas.metacat.MetaCatUtil;
  import edu.ucsb.nceas.metacat.DBConnection;
  import org.geotools.feature.Feature;
  
  /* 
   * Harvests spatial data from metacat and saves to persistent cache
   */
  public class SpatialHarvester {
   
    private static Logger log = Logger.getLogger(SpatialHarvester.class.getName());
   
    private DBConnection dbconn;
   
    /** constructor to initialize db connection **/
    public SpatialHarvester() {
        try {
            dbconn = new DBConnection();
        } catch( Exception e ) {
            log.error("Error getting docids from queryAllDocids");
            e.printStackTrace();
        }
    }
   
    /*
     * Closes the database connection
     * MUST be called after you're done with
     * the SpatialHarvester
     */
    public void destroy() {
        try {
            dbconn.close();
        } catch( Exception e ) {
            log.error("Error closing out dbconn");
            e.printStackTrace();
        }
    }
  
    /**
     * Returns a Vector of all the docids in the xml_path_index tables
     */
    protected Vector queryAllDocids() {
      Vector _docs = new Vector();
      PreparedStatement pstmt = null;
      ResultSet rs = null;
  
      String query = "select distinct docid from xml_path_index";
  
      try {
        pstmt = dbconn.prepareStatement(query);
        pstmt.execute();
        rs = pstmt.getResultSet();
        while (rs.next()) {
          String docid = rs.getString(1);
          //log.fatal("adding docid: " + docid);
          _docs.add(docid);
      }
        rs.close();
        pstmt.close();
      }
      catch(Exception e) {
        log.error("Error getting docids from queryAllDocids");
        e.printStackTrace();
      }
      return _docs;
    }
  
    /*
     * Currently just a wrapper around the harvester
     * Eventually we can use this method as a
     * timed que like the indexing process
     */                   
    public void addToUpdateQue( String docid ) {
        harvestDocument(docid);
    }
  
    /*
     * Delete from spatial cache
     * Just a wrapper around delete for now
     */
    public void addToDeleteQue( String docid ) {
        deleteDocument(docid);
    }
  
    /*
     * Given a docid, will attempt to delete
     * from spatial cache
     */
    public void deleteDocument( String docid ) {
  
       // Read the existing spatial dataset cache
       SpatialDataset sds = new SpatialDataset();
  
       try {
           // Delete both the polygon(s) and point(s)
           sds.delete( "polygon" , docid ); 
           sds.delete( "point" , docid ); 
       } catch (IOException e) {
           log.error("IOException while deleting from spatial cache");
       }
  
       log.info(" --------- Spatial Harvester - Deleted from spatial cache : " + docid );
    }      
  
  
    /*
     * Given a docid, will update the spatial cache accordingly
     */
    public void harvestDocument( String docid ) {
  
       // Read the existing spatial dataset cache
       SpatialDataset sds = new SpatialDataset();
  
       // insert OR update the spatial cache
       // SpatialDataset.insertOrUpdate takes care of the difference 
       SpatialDocument sdoc = new SpatialDocument( docid, dbconn );
  
       try {
           Feature polygonFeature = sdoc.getPolygonFeature();
           sds.insertOrUpdate("polygon", polygonFeature, docid );
  
           Feature pointFeature = sdoc.getPointFeature();
           sds.insertOrUpdate("point", pointFeature, docid );
           log.info(" --------- Spatial Harvester - spatial cache updated for : " + docid );
       } catch (IOException e) {
           log.error("IOException while performing spatial harvest ");
       }
    }
  
    /*
     * Completely regenerates the spatial cache
     */
    public void regenerate() {
        
        // Create new Spatial Dataset
        SpatialDataset sds = new SpatialDataset();
  
        // Get list of all docids in the database
        Vector docids = queryAllDocids(); 
         
        for (int i = 0; i < docids.size(); i++) {
            SpatialDocument sdoc = new SpatialDocument( (String)docids.elementAt(i), dbconn );
  
            // Get the polygon representation of SpatialDocument
            // and add it to the spatial dataset
            Feature polygonFeature = sdoc.getPolygonFeature();
            sds.add("polygon", polygonFeature );
  
            // Get the point representation of SpatialDocument
            // and add it to the spatial dataset
            Feature pointFeature = sdoc.getPointFeature();
            sds.add("point", pointFeature );
  
            log.info(" ****** Spatial harvest of docid " + docids.elementAt(i) );
        }
  
        // save SpatialDataset
        sds.save();
  
    }
  
  }
  
  
  
  1.1                  metacat/src/edu/ucsb/nceas/metacat/spatial/WmsFilter.java
  
  Index: WmsFilter.java
  ===================================================================
  /* WMS Filter
   * Author: MP
   * Status: Just a test
   * MPTODO: make this a true servlet filter to append sld to any incoming wms request
   */
  package edu.ucsb.nceas.metacat.spatial;
  
  import javax.servlet.*;
  import javax.servlet.http.*;
  import java.io.IOException;
  import java.util.Enumeration;
  
  public final class WmsFilter implements Filter {
     private FilterConfig filterConfig = null;
  
     public void init(FilterConfig filterConfig) 
        throws ServletException {
        this.filterConfig = filterConfig;
     }
  
     public void destroy() {
        this.filterConfig = null;
     }
  
     public void doFilter(ServletRequest request,
        ServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
  
        if (filterConfig == null)
           return;
  
        System.out.println("\n===============");
  
        System.out.println(" The filter Works !!!");
        long before = System.currentTimeMillis();
        
        // Attributes != Paramters but there is no setParameter
        //request.setAttribute("SLD", "http://pmark.msi.ucsb.edu:8180/knb/style/skins/ebm/spatial/data_bounds_style.sld");
  
        Enumeration e = request.getParameterNames();
        while( e.hasMoreElements() ) {
            String name = (String) e.nextElement();
            System.out.println( name + " = " + request.getParameter(name));
        }
  
        
        chain.doFilter(request, response);
        long after = System.currentTimeMillis();
        System.out.println(" *** Time  " + (after - before) + "ms");
  
  
        System.out.println("===============\n");
  
        // A simple redirect won't work since it will filter itself endlessly
        //HttpServletResponse hres = (HttpServletResponse) response;
        //HttpServletRequest hreq = (HttpServletRequest) response;
        //hres.sendRedirect( hreq.getRequestURL().toString() );
     }
  }
  
  
  


More information about the Metacat-cvs mailing list