@Override
  public void postCreateFeatureType(
      SimpleFeatureType featureType, DatabaseMetaData metadata, String schemaName, Connection cx)
      throws SQLException {
    // figure out if the table has a spatial index and mark the feature type as so
    for (AttributeDescriptor ad : featureType.getAttributeDescriptors()) {
      if (!(ad instanceof GeometryDescriptor)) {
        continue;
      }

      GeometryDescriptor gd = (GeometryDescriptor) ad;
      String idxTableName = "idx_" + featureType.getTypeName() + "_" + gd.getLocalName();

      ResultSet rs =
          metadata.getTables(
              null,
              dataStore.escapeNamePattern(metadata, schemaName),
              dataStore.escapeNamePattern(metadata, idxTableName),
              new String[] {"TABLE"});
      try {
        if (rs.next()) {
          gd.getUserData().put(SPATIALITE_SPATIAL_INDEX, idxTableName);
        }
      } finally {
        dataStore.closeSafe(rs);
      }
    }
  }
  @Override
  public FeatureIterator getSortedFeatures(
      GeometryDescriptor geom,
      ReferencedEnvelope latLongEnv,
      ReferencedEnvelope nativeEnv,
      Connection cacheConn)
      throws Exception {
    FeatureSource fs = featureType.getFeatureSource(null, null);

    // build the bbox filter
    FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);

    BBOX filter =
        ff.bbox(
            geom.getLocalName(),
            nativeEnv.getMinX(),
            nativeEnv.getMinY(),
            nativeEnv.getMaxX(),
            nativeEnv.getMaxY(),
            null);

    // build an optimized query (only the necessary attributes
    Query q = new Query();
    q.setFilter(filter);
    // TODO: enable this when JTS learns how to compute centroids
    // without triggering the
    // generation of Coordinate[] out of the sequences...
    // q.setHints(new Hints(Hints.JTS_COORDINATE_SEQUENCE_FACTORY,
    // PackedCoordinateSequenceFactory.class));
    q.setPropertyNames(new String[] {geom.getLocalName()});

    // return the reader
    return fs.getFeatures(q).features();
  }
Example #3
0
  @Override
  public void encodeGeometryColumn(
      GeometryDescriptor gatt, String prefix, int srid, Hints hints, StringBuffer sql) {

    boolean geography =
        "geography".equals(gatt.getUserData().get(JDBCDataStore.JDBC_NATIVE_TYPENAME));

    if (geography) {
      sql.append("encode(ST_AsBinary(");
      encodeColumnName(prefix, gatt.getLocalName(), sql);
      sql.append("),'base64')");
    } else {
      boolean force2D =
          hints != null
              && hints.containsKey(Hints.FEATURE_2D)
              && Boolean.TRUE.equals(hints.get(Hints.FEATURE_2D));

      if (force2D) {
        sql.append("encode(ST_AsBinary(ST_Force_2D(");
        encodeColumnName(prefix, gatt.getLocalName(), sql);
        sql.append(")),'base64')");
      } else {
        sql.append("encode(ST_AsEWKB(");
        encodeColumnName(prefix, gatt.getLocalName(), sql);
        sql.append("),'base64')");
      }
    }
  }
  /*
   * Adds a feature layer to the geopackage.
   */
  void addFeatureLayer(
      GeoPackage geopkg, FeatureLayer layer, MapLayerInfo mapLayer, WMSMapContent map)
      throws IOException {

    FeatureEntry e = new FeatureEntry();
    initEntry(e, layer, mapLayer, map);

    Filter filter = layer.getQuery().getFilter();
    GeometryDescriptor gd = mapLayer.getFeature().getFeatureType().getGeometryDescriptor();
    if (gd != null) {
      Envelope bnds = bounds(map);
      BBOX bboxFilter =
          filterFactory.bbox(
              gd.getLocalName(),
              bnds.getMinX(),
              bnds.getMinY(),
              bnds.getMaxX(),
              bnds.getMaxY(),
              map.getRequest().getSRS());
      filter = filterFactory.and(filter, bboxFilter);
    }

    LOGGER.fine("Creating feature entry" + e.getTableName());
    geopkg.add(e, layer.getSimpleFeatureSource(), filter);
  }
  /**
   * Forces the specified CRS on geometry attributes (all or some, depends on the parameters).
   *
   * @param schema the original schema
   * @param crs the forced crs
   * @param forceOnlyMissing if true, will force the specified crs only on the attributes that do
   *     miss one
   * @return
   * @throws SchemaException
   */
  public static SimpleFeatureType transform(
      SimpleFeatureType schema, CoordinateReferenceSystem crs, boolean forceOnlyMissing)
      throws SchemaException {
    SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
    tb.setName(schema.getTypeName());
    tb.setNamespaceURI(schema.getName().getNamespaceURI());
    tb.setAbstract(schema.isAbstract());

    GeometryDescriptor defaultGeometryType = null;
    for (int i = 0; i < schema.getAttributeCount(); i++) {
      AttributeDescriptor attributeType = schema.getDescriptor(i);
      if (attributeType instanceof GeometryDescriptor) {
        GeometryDescriptor geometryType = (GeometryDescriptor) attributeType;
        AttributeDescriptor forced;

        tb.descriptor(geometryType);
        if (!forceOnlyMissing || geometryType.getCoordinateReferenceSystem() == null) {
          tb.crs(crs);
        }

        tb.add(geometryType.getLocalName(), geometryType.getType().getBinding());
      } else {
        tb.add(attributeType);
      }
    }
    if (schema.getGeometryDescriptor() != null) {
      tb.setDefaultGeometry(schema.getGeometryDescriptor().getLocalName());
    }

    tb.setSuperType((SimpleFeatureType) schema.getSuper());

    return tb.buildFeatureType();
  }
 @Override
 public SimpleFeature decode(String recordId, String[] csvRecord) {
   SimpleFeatureType featureType = getFeatureType();
   SimpleFeatureBuilder builder = new SimpleFeatureBuilder(featureType);
   GeometryDescriptor geometryDescriptor = featureType.getGeometryDescriptor();
   GeometryFactory geometryFactory = new GeometryFactory();
   Double lat = null, lng = null;
   String[] headers = csvFileState.getCSVHeaders();
   for (int i = 0; i < headers.length; i++) {
     String header = headers[i];
     if (i < csvRecord.length) {
       String value = csvRecord[i].trim();
       if (geometryDescriptor != null && header.equals(latField)) {
         lat = Double.valueOf(value);
       } else if (geometryDescriptor != null && header.equals(lngField)) {
         lng = Double.valueOf(value);
       } else {
         builder.set(header, value);
       }
     } else {
       builder.set(header, null);
     }
   }
   if (geometryDescriptor != null && lat != null && lng != null) {
     Coordinate coordinate = new Coordinate(lng, lat);
     Point point = geometryFactory.createPoint(coordinate);
     builder.set(geometryDescriptor.getLocalName(), point);
   }
   return builder.buildFeature(csvFileState.getTypeName() + "-" + recordId);
 }
  /**
   * Creates a new SimpleFeature for <code>targetType</code> that holds the common attributes from
   * <code>sourceFeature</code> and the buffered geometry.
   *
   * @param sourceFeature the original SimpleFeature from which to extract matching attributes for
   *     the new SimpleFeature, or <code>null</code> if the new SimpleFeature has to have empty
   *     attributes other than the default geometry.
   * @param targetType
   * @param bufferedGeometry the product geometry of running {@link BufferOp} over the default
   *     geometry of <code>sourceFeature</code> with the parameters provided to this operation.
   * @return a new SimpleFeature of type <code>targetType</code> holding the common attributes with
   *     <code>sourceFeature</code> and <code>bufferedGeometry</code> as the feature's default
   *     geometry
   * @throws SOProcessException
   */
  @SuppressWarnings("unchecked")
  private SimpleFeature createBufferedFeature(
      SimpleFeature sourceFeature, SimpleFeatureType targetType, Geometry bufferedGeometry)
      throws SOProcessException {

    SimpleFeature newFeature;
    try {
      newFeature = DataUtilities.template(targetType);
      final GeometryDescriptor targetGeometryType = targetType.getDefaultGeometry();

      if (sourceFeature != null) {
        GeoToolsUtils.match(sourceFeature, newFeature);
      }

      final String attName = targetGeometryType.getLocalName();
      final Class geomClass = targetGeometryType.getType().getBinding();
      bufferedGeometry = GeometryUtil.adapt(bufferedGeometry, geomClass);

      newFeature.setAttribute(attName, bufferedGeometry);

    } catch (IllegalAttributeException e) {
      throw new SOProcessException(e.getMessage(), e);
    }
    return newFeature;
  }
  @Override
  public void createSchema(SimpleFeatureType featureType) throws IOException {
    List<String> header = new ArrayList<String>();

    GeometryDescriptor geometryDescrptor = featureType.getGeometryDescriptor();
    if (geometryDescrptor != null
        && CRS.equalsIgnoreMetadata(
            DefaultGeographicCRS.WGS84, geometryDescrptor.getCoordinateReferenceSystem())
        && geometryDescrptor.getType().getBinding().isAssignableFrom(Point.class)) {
      header.add(this.latField);
      header.add(this.lngField);
    } else {
      throw new IOException(
          "Unable use '"
              + this.latField
              + "' / '"
              + this.lngField
              + "' to represent "
              + geometryDescrptor);
    }
    for (AttributeDescriptor descriptor : featureType.getAttributeDescriptors()) {
      if (descriptor instanceof GeometryDescriptor) continue;
      header.add(descriptor.getLocalName());
    }
    // Write out header, producing an empty file of the correct type
    CsvWriter writer = new CsvWriter(new FileWriter(this.csvFileState.getFile()), ',');
    try {
      writer.writeRecord(header.toArray(new String[header.size()]));
    } finally {
      writer.close();
    }
  }
  public void testGeometryMetadataTable() throws Exception {
    testSetup.setupMetadataTable(dataStore);

    GeometryDescriptor gd =
        dataStore.getFeatureSource(tname("gtmeta")).getSchema().getGeometryDescriptor();
    assertEquals(Point.class, gd.getType().getBinding());
    assertEquals(4326, (int) CRS.lookupEpsgCode(gd.getCoordinateReferenceSystem(), false));
  }
  public static <T extends FeatureType, F extends org.opengis.feature.Feature> void featuresToJson(
      FeatureCollection<T, F> collection, JSONBuilder json, boolean returnGeometry)
      throws IOException {
    FeatureIterator<F> iterator = collection.features();

    T schema = collection.getSchema();
    json.object().key("objectIdFieldName").value("objectid").key("globalIdFieldName").value("");

    if (returnGeometry) {
      GeometryDescriptor geometryDescriptor = schema.getGeometryDescriptor();
      if (geometryDescriptor == null)
        throw new RuntimeException(
            "No geometry descriptor for type " + schema + "; " + schema.getDescriptors());
      GeometryType geometryType = geometryDescriptor.getType();
      if (geometryType == null) throw new RuntimeException("No geometry type for type " + schema);
      Class<?> binding = geometryType.getBinding();
      if (binding == null) throw new RuntimeException("No binding for geometry type " + schema);
      GeometryTypeEnum geometryTypeEnum = GeometryTypeEnum.forJTSClass(binding);
      json.key("geometryType").value(geometryTypeEnum.getGeometryType());
    }

    if (schema.getCoordinateReferenceSystem() != null) {
      try {
        SpatialReference sr = SpatialReferences.fromCRS(schema.getCoordinateReferenceSystem());
        json.key("spatialReference");
        SpatialReferenceEncoder.toJson(sr, json);
      } catch (FactoryException e) {
        throw new RuntimeException(e);
      }
    }

    json.key("fields").array();
    for (PropertyDescriptor desc : schema.getDescriptors()) {
      if (schema.getGeometryDescriptor() != null
          && !desc.getName().equals(schema.getGeometryDescriptor().getName())) {
        descriptorToJson(desc, json);
      }
    }
    json.endArray();

    try {
      json.key("features");
      json.array();
      while (iterator.hasNext()) {
        F feature = iterator.next();
        featureToJson(feature, json, returnGeometry);
      }
      json.endArray();
    } finally {
      iterator.close();
    }
    json.endObject();
  }
Example #11
0
  public void testImportCSVIndirect() throws Exception {
    File dir = unpack("csv/locations.zip");
    String wsName = getCatalog().getDefaultWorkspace().getName();

    DataStoreInfo h2DataStore = createH2DataStore(wsName, "csvindirecttest");
    SpatialFile importData = new SpatialFile(new File(dir, "locations.csv"));

    ImportContext context = importer.createContext(importData, h2DataStore);
    assertEquals(1, context.getTasks().size());
    ImportTask task = context.getTasks().get(0);

    TransformChain transformChain = task.getTransform();
    transformChain.add(new AttributesToPointGeometryTransform("LAT", "LON"));
    assertEquals(ImportTask.State.NO_CRS, task.getState());

    LayerInfo layer = task.getLayer();
    ResourceInfo resource = layer.getResource();
    resource.setSRS("EPSG:4326");

    assertTrue("Item not ready", importer.prep(task));
    assertEquals(ImportTask.State.READY, task.getState());

    context.updated();
    assertEquals(ImportContext.State.PENDING, context.getState());
    importer.run(context);

    assertEquals(ImportContext.State.COMPLETE, context.getState());
    FeatureTypeInfo fti = (FeatureTypeInfo) resource;
    SimpleFeatureType featureType = (SimpleFeatureType) fti.getFeatureType();
    GeometryDescriptor geometryDescriptor = featureType.getGeometryDescriptor();
    assertNotNull("Expecting geometry", geometryDescriptor);
    assertEquals("Invalid geometry name", "location", geometryDescriptor.getLocalName());
    assertEquals(3, featureType.getAttributeCount());
    FeatureSource<? extends FeatureType, ? extends Feature> featureSource =
        fti.getFeatureSource(null, null);
    FeatureCollection<? extends FeatureType, ? extends Feature> features =
        featureSource.getFeatures();
    assertEquals(9, features.size());
    FeatureIterator<? extends Feature> featureIterator = features.features();
    assertTrue("Expected features", featureIterator.hasNext());
    SimpleFeature feature = (SimpleFeature) featureIterator.next();
    assertNotNull(feature);
    assertEquals("Invalid city attribute", "Trento", feature.getAttribute("CITY"));
    assertEquals("Invalid number attribute", 140, feature.getAttribute("NUMBER"));
    Object geomAttribute = feature.getAttribute("location");
    assertNotNull("Expected geometry", geomAttribute);
    Point point = (Point) geomAttribute;
    Coordinate coordinate = point.getCoordinate();
    assertEquals("Invalid x coordinate", 11.12, coordinate.x, 0.1);
    assertEquals("Invalid y coordinate", 46.07, coordinate.y, 0.1);
    featureIterator.close();
  }
  /**
   * Applies transform to all geometry attribute.
   *
   * @param feature Feature to be transformed
   * @param schema Schema for target transformation - transform( schema, crs )
   * @param transform MathTransform used to transform coordinates - reproject( crs, crs )
   * @return transformed Feature of type schema
   * @throws TransformException
   * @throws MismatchedDimensionException
   * @throws IllegalAttributeException
   */
  public static SimpleFeature transform(
      SimpleFeature feature, SimpleFeatureType schema, MathTransform transform)
      throws MismatchedDimensionException, TransformException, IllegalAttributeException {
    feature = SimpleFeatureBuilder.copy(feature);

    GeometryDescriptor geomType = schema.getGeometryDescriptor();
    Geometry geom = (Geometry) feature.getAttribute(geomType.getLocalName());

    geom = JTS.transform(geom, transform);

    feature.setAttribute(geomType.getLocalName(), geom);

    return feature;
  }
  /**
   * Create a new helper to work with a {@code MapLayer} that has vector feature data.
   *
   * @param layer the map layer
   * @param geomAttributeName the name of the geometry attribute for {@code Features}
   * @param geomClass the geometry class
   */
  public VectorLayerHelper(MapContext context, MapLayer layer) {
    super(context, layer.getFeatureSource().getSchema().getCoordinateReferenceSystem());

    this.layerRef = new WeakReference<MapLayer>(layer);

    final GeometryDescriptor geomDesc =
        layer.getFeatureSource().getSchema().getGeometryDescriptor();
    this.attrName = geomDesc.getLocalName();

    final Class<? extends Geometry> geomClass =
        (Class<? extends Geometry>) geomDesc.getType().getBinding();
    final Geometries type = Geometries.getForBinding(geomClass);
    this.isPolygonGeometry = (type == Geometries.POLYGON || type == Geometries.MULTIPOLYGON);
  }
  // todo - add API doc describing what the method does (nf,ts - 2012-04-23)
  @Override
  public void setUserDataOf(SimpleFeatureType compatibleFeatureType) {

    compatibleFeatureType
        .getUserData()
        .put(PROPERTY_NAME_PLACEMARK_DESCRIPTOR, getClass().getName());

    final org.opengis.feature.type.GeometryDescriptor geometryDescriptor =
        compatibleFeatureType.getGeometryDescriptor();
    if (geometryDescriptor != null) {
      compatibleFeatureType
          .getUserData()
          .put(PROPERTY_NAME_DEFAULT_GEOMETRY, geometryDescriptor.getLocalName());
    }
  }
Example #15
0
  private Integer getSRID(GeometryDescriptor gDescr) {
    Integer result = null;
    if (gDescr != null) result = (Integer) gDescr.getUserData().get(JDBCDataStore.JDBC_NATIVE_SRID);

    if (result == null) result = currentSRID;
    return result;
  }
Example #16
0
 @Override
 public void encodeGeometryColumn(
     GeometryDescriptor gatt, String prefix, int srid, Hints hints, StringBuffer sql) {
   sql.append("AsBinary(");
   encodeColumnName(prefix, gatt.getLocalName(), sql);
   sql.append(")");
 }
    private boolean intersects(SimpleFeature feature) {
      GeometryDescriptor geomDescriptor = getGeometryAttDescriptor(feature.getFeatureType());

      Geometry bboxGeom = new GeometryFactory().toGeometry(bbox);

      Geometry geom = (Geometry) feature.getAttribute(geomDescriptor.getName());

      try {
        return geom.intersects(bboxGeom);
      } catch (Exception e) {
        // ok so exception happened during intersection.  This usually means geometry is a little
        // crazy
        // what to do?...
        EditPlugin.log("Can't do intersection so I'm assuming they intersect", e); // $NON-NLS-1$
        return false;
      }
    }
Example #18
0
  /**
   * Returns the vector icon associated to the specified geometry descriptor
   *
   * @param gd
   */
  public ResourceReference getVectoryIcon(GeometryDescriptor gd) {
    if (gd == null) {
      return GEOMETRY_ICON;
    }

    Class geom = gd.getType().getBinding();
    return getVectorIcon(geom);
  }
Example #19
0
  /**
   * if the query has been parsed as just a where clause filter, or has no filter at all, the result
   * count calculation is optimized by selecting a <code>count()</code> single row. If the filter
   * involves any kind of spatial filter, such as BBOX, the calculation can't be optimized by this
   * way, because the ArcSDE Java API throws a <code>"DATABASE LEVEL
   * ERROR OCURRED"</code> exception. So, in this case, a query over the shape field is made and the
   * result is traversed counting the number of rows inside a while loop
   */
  public int calculateResultCount() throws IOException {

    final SimpleFeatureType schema = this.schema;
    final GeometryDescriptor geometryDescriptor = schema.getGeometryDescriptor();

    final String colName;
    if (geometryDescriptor == null) {
      // gemetryless type, use any other column for the query
      colName = schema.getDescriptor(0).getLocalName();
    } else {
      colName = geometryDescriptor.getLocalName();
    }
    final SeQueryInfo qInfo = filters.getQueryInfo(new String[] {colName});

    final SeFilter[] spatialFilters = filters.getSpatialFilters();

    final Command<Integer> countCmd =
        new Command<Integer>() {
          @Override
          public Integer execute(ISession session, SeConnection connection)
              throws SeException, IOException {

            SeQuery query = new SeQuery(connection);
            try {
              versioningHandler.setUpStream(session, query);

              if (spatialFilters != null && spatialFilters.length > 0) {
                query.setSpatialConstraints(SeQuery.SE_OPTIMIZE, true, spatialFilters);
              }

              SeTable.SeTableStats tableStats =
                  query.calculateTableStatistics(
                      "*", SeTable.SeTableStats.SE_COUNT_STATS, qInfo, 0);

              int actualCount = tableStats.getCount();
              return new Integer(actualCount);
            } finally {
              query.close();
            }
          }
        };

    final Integer count = session.issue(countCmd);
    return count.intValue();
  }
Example #20
0
  /** Convenient method to just calculate the resulting bound box of a given query. */
  public static Envelope calculateQueryExtent(
      final ISession session,
      final FeatureTypeInfo typeInfo,
      final Query query,
      final ArcSdeVersionHandler versioningHandler)
      throws IOException {

    final SimpleFeatureType fullSchema = typeInfo.getFeatureType();
    final GeometryDescriptor geometryDescriptor = fullSchema.getGeometryDescriptor();
    if (geometryDescriptor == null) {
      return null;
    }
    final String defaultGeomAttName = geometryDescriptor.getLocalName();

    // we're calculating the bounds, so we'd better be sure and add the
    // spatial column to the query's propertynames
    final Query realQuery = new Query(query);
    realQuery.setPropertyNames(new String[] {defaultGeomAttName});

    final ArcSDEQuery boundsQuery;

    if (typeInfo.isInProcessView()) {
      final SeQueryInfo definitionQuery = typeInfo.getSdeDefinitionQuery();
      final PlainSelect viewSelectStatement = typeInfo.getDefinitionQuery();
      boundsQuery =
          createInprocessViewQuery(
              session, fullSchema, realQuery, definitionQuery, viewSelectStatement);
    } else {
      final FIDReader fidStrategy = typeInfo.getFidStrategy();
      boundsQuery = createQuery(session, fullSchema, realQuery, fidStrategy, versioningHandler);
    }

    Envelope queryExtent = null;
    try {
      Filter unsupportedFilter = boundsQuery.getFilters().getUnsupportedFilter();
      if (unsupportedFilter == Filter.INCLUDE) {
        // we can only use an optimized bounds calculation if the
        // query is fully supported by sde
        queryExtent = boundsQuery.calculateQueryExtent();
      }
    } finally {
      boundsQuery.close();
    }
    return queryExtent;
  }
Example #21
0
  /** Retrieve information about the feature geometry */
  private void setGeometry() {
    GeometryDescriptor geomDesc = featureSource.getSchema().getGeometryDescriptor();
    geometryAttributeName = geomDesc.getLocalName();

    Class<?> clazz = geomDesc.getType().getBinding();

    if (Polygon.class.isAssignableFrom(clazz) || MultiPolygon.class.isAssignableFrom(clazz)) {
      geometryType = GeomType.POLYGON;

    } else if (LineString.class.isAssignableFrom(clazz)
        || MultiLineString.class.isAssignableFrom(clazz)) {

      geometryType = GeomType.LINE;

    } else {
      geometryType = GeomType.POINT;
    }
  }
  /**
   * Connect to the original FeatureConnection
   *
   * @param originalFC FeatureCollection
   * @param intersList FeatureCollection
   */
  public UnionFeatureCollection(
      final FeatureCollection<Feature> inputFC,
      final FeatureCollection<Feature> unionFC,
      final String inputGeomName,
      final String unionGeomName) {

    super(inputFC);
    this.unionFC = unionFC;

    /*
     * We ensure that inputGeomName and unionGeomName are not null and we get the CRS of
     * these geometry. This in order to genereate the new FeatureType based on two FeatureType
     * and with only one geometry (in this case inputGeomName)
     * If inputGeomName or unionGeomName is null, we use default geometry name and CRS.
     */
    CoordinateReferenceSystem geometryCRS;
    if (inputGeomName == null) {
      this.inputGeomName =
          inputFC.getFeatureType().getGeometryDescriptor().getName().getLocalPart();
      geometryCRS = inputFC.getFeatureType().getGeometryDescriptor().getCoordinateReferenceSystem();
    } else {
      this.inputGeomName = inputGeomName;
      final GeometryDescriptor buffDesc =
          (GeometryDescriptor) inputFC.getFeatureType().getDescriptor(inputGeomName);
      geometryCRS = buffDesc.getCoordinateReferenceSystem();
    }

    if (unionGeomName == null) {
      this.unionGeomName =
          unionFC.getFeatureType().getGeometryDescriptor().getName().getLocalPart();
    } else {
      this.unionGeomName = unionGeomName;
    }

    // Create the new FeatureType which concatenate two FeatureCollection FeatureType but with only
    // one geometry
    // (inputGeomName)
    this.newFeatureType =
        Union.mergeType(
            inputFC.getFeatureType(), unionFC.getFeatureType(), this.inputGeomName, geometryCRS);
  }
  public static SimpleFeatureType retype(SimpleFeatureType original, List<String> types) {
    SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();

    // initialize the builder
    b.init(original);

    // clear the attributes
    b.attributes().clear();

    // add attributes in order
    for (int i = 0; i < types.size(); i++) {
      b.add(original.getDescriptor(types.get(i)));
    }

    // handle default geometry
    GeometryDescriptor defaultGeometry = original.getGeometryDescriptor();
    if (defaultGeometry != null && types.contains(defaultGeometry.getLocalName())) {
      b.setDefaultGeometry(defaultGeometry.getLocalName());
    }

    return b.buildFeatureType();
  }
  private Query reprojectFilter(Query query) throws IOException {
    final Filter originalFilter = query.getFilter() != null ? query.getFilter() : Filter.INCLUDE;
    if (Filter.INCLUDE.equals(originalFilter)) {
      return query;
    }

    final SimpleFeatureType nativeFeatureType = getSchema();
    final GeometryDescriptor geom = nativeFeatureType.getGeometryDescriptor();
    // if no geometry involved, no reprojection needed
    if (geom == null) {
      return query;
    }

    final FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2(null);

    try {
      CoordinateReferenceSystem nativeCRS = geom.getCoordinateReferenceSystem();

      // now we apply a default to all geometries and bbox in the filter
      DefaultCRSFilterVisitor defaultCRSVisitor = new DefaultCRSFilterVisitor(ff, nativeCRS);
      final Filter defaultedFilter = (Filter) originalFilter.accept(defaultCRSVisitor, null);

      // and then we reproject all geometries so that the datastore
      // receives
      // them in the native projection system (or the forced one, in case
      // of force)
      ReprojectingFilterVisitor reprojectingVisitor =
          new ReprojectingFilterVisitor(ff, nativeFeatureType);
      final Filter reprojectedFilter = (Filter) defaultedFilter.accept(reprojectingVisitor, null);

      Query reprojectedQuery = new Query(query);
      reprojectedQuery.setFilter(reprojectedFilter);
      return reprojectedQuery;
    } catch (Exception e) {
      throw new DataSourceException("Had troubles handling filter reprojection...", e);
    }
  }
  /**
   * Create a SimpleFeatureType with the same content; just updating the geometry attribute to match
   * the provided coordinate reference system.
   *
   * @param original SimpleFeatureType
   * @param crs CoordinateReferenceSystem of result
   * @return SimpleFeatureType updated with the provided CoordinateReferenceSystem
   */
  public static SimpleFeatureType retype(
      SimpleFeatureType original, CoordinateReferenceSystem crs) {
    SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();

    // initialize the builder
    b.init(original);

    // clear the attributes
    b.attributes().clear();

    // add attributes in order
    for (AttributeDescriptor descriptor : original.getAttributeDescriptors()) {
      if (descriptor instanceof GeometryDescriptor) {
        GeometryDescriptor geometryDescriptor = (GeometryDescriptor) descriptor;
        AttributeTypeBuilder adjust = new AttributeTypeBuilder(b.factory);
        adjust.init(geometryDescriptor);
        adjust.setCRS(crs);
        b.add(adjust.buildDescriptor(geometryDescriptor.getLocalName()));
        continue;
      }
      b.add(descriptor);
    }
    return b.buildFeatureType();
  }
Example #26
0
  @Override
  public void postCreateTable(String schemaName, SimpleFeatureType featureType, Connection cx)
      throws SQLException, IOException {

    // create any geometry columns entries after the fact
    for (AttributeDescriptor ad : featureType.getAttributeDescriptors()) {
      if (ad instanceof GeometryDescriptor) {
        GeometryDescriptor gd = (GeometryDescriptor) ad;
        StringBuffer sql = new StringBuffer("INSERT INTO geometry_columns VALUES (");

        // table name
        sql.append("'").append(featureType.getTypeName()).append("',");

        // geometry name
        sql.append("'").append(gd.getLocalName()).append("',");

        // type
        String gType =
            Geometries.getForBinding((Class<? extends Geometry>) gd.getType().getBinding())
                .getName();
        if (gType == null) {
          throw new IOException("Unknown geometry type: " + gd.getType().getBinding());
        }
        sql.append("'").append(gType).append("',");

        // coord dimension
        sql.append(2).append(",");

        // srid
        Integer epsgCode = null;
        if (gd.getCoordinateReferenceSystem() != null) {
          CoordinateReferenceSystem crs = gd.getCoordinateReferenceSystem();
          try {
            epsgCode = CRS.lookupEpsgCode(crs, true);
          } catch (Exception e) {
          }
        }
        if (epsgCode == null) {
          throw new IOException("Unable to find epsg code code.");
        }
        sql.append(epsgCode).append(",");

        // spatial index enabled
        sql.append(0).append(")");

        LOGGER.fine(sql.toString());
        Statement st = cx.createStatement();
        try {
          st.executeUpdate(sql.toString());
        } finally {
          dataStore.closeSafe(st);
        }
      }
    }
  }
 /** Maps the default geometry attribute regardless of whether they are the same type. */
 @SuppressWarnings("unchecked")
 private static void mapGeometryAttributes(
     SimpleFeatureType sourceSchema,
     SimpleFeatureType targetSchema,
     Map<String, String> queryAttributes) {
   // Now we'll match the geometry on type only. I don't care if it has the same type name.
   GeometryDescriptor defaultGeometry = targetSchema.getGeometryDescriptor();
   if (defaultGeometry == null) {
     return;
   } else if (!queryAttributes.containsKey(defaultGeometry.getName())) {
     // first check source's default geom and see if it matches
     Class<?> binding = sourceSchema.getGeometryDescriptor().getType().getBinding();
     if (defaultGeometry.getType().getBinding().isAssignableFrom(binding)) {
       queryAttributes.put(
           defaultGeometry.getName().getLocalPart(),
           sourceSchema.getGeometryDescriptor().getName().getLocalPart());
     } else {
       // we have to look through all the source attributes looking for a geometry that
       // matches.
       boolean found = false;
       for (int i = 0; i < sourceSchema.getAttributeCount(); i++) {
         AttributeDescriptor source = sourceSchema.getDescriptor(i);
         if (defaultGeometry
             .getType()
             .getBinding()
             .isAssignableFrom(source.getType().getBinding())) {
           queryAttributes.put(
               defaultGeometry.getName().getLocalPart(), source.getName().getLocalPart());
           found = true;
           break;
         }
       }
       // ok so we're going to have to do some transformations. Match default geometries
       // then.
       if (!found) {
         queryAttributes.put(
             defaultGeometry.getName().getLocalPart(),
             sourceSchema.getGeometryDescriptor().getName().getLocalPart());
       }
     }
   }
 }
  /**
   * Clones the given schema, changing the geometry attribute to match the given dimensionality.
   *
   * @param schema schema to clone
   * @param dimensionality dimensionality for the geometry 1= points, 2= lines, 3= polygons
   */
  private FeatureType cloneWithDimensionality(FeatureType schema, int dimensionality) {
    SimpleFeatureType simpleFt = (SimpleFeatureType) schema;
    SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
    builder.setName(schema.getName());
    builder.setCRS(schema.getCoordinateReferenceSystem());
    for (AttributeDescriptor desc : simpleFt.getAttributeDescriptors()) {
      if (isMixedGeometry(desc)) {
        GeometryDescriptor geomDescriptor = (GeometryDescriptor) desc;
        GeometryType geomType = geomDescriptor.getType();

        Class<?> geometryClass = getGeometryForDimensionality(dimensionality);

        GeometryType gt =
            new GeometryTypeImpl(
                geomType.getName(),
                geometryClass,
                geomType.getCoordinateReferenceSystem(),
                geomType.isIdentified(),
                geomType.isAbstract(),
                geomType.getRestrictions(),
                geomType.getSuper(),
                geomType.getDescription());

        builder.add(
            new GeometryDescriptorImpl(
                gt,
                geomDescriptor.getName(),
                geomDescriptor.getMinOccurs(),
                geomDescriptor.getMaxOccurs(),
                geomDescriptor.isNillable(),
                geomDescriptor.getDefaultValue()));
      } else {
        builder.add(desc);
      }
    }
    schema = builder.buildFeatureType();
    return schema;
  }
Example #29
0
  @Override
  public void postCreateTable(String schemaName, SimpleFeatureType featureType, Connection cx)
      throws SQLException {

    Statement st = cx.createStatement();
    String tableName = featureType.getTypeName();

    try {
      // post process the feature type and set up constraints based on geometry type
      for (PropertyDescriptor ad : featureType.getDescriptors()) {
        if (ad instanceof GeometryDescriptor) {
          GeometryDescriptor gd = (GeometryDescriptor) ad;
          Class binding = ad.getType().getBinding();
          String propertyName = ad.getName().getLocalPart();

          // create a spatial index
          int epsg = -1;
          try {
            CoordinateReferenceSystem crs = gd.getCoordinateReferenceSystem();
            if (crs == null) {
              continue;
            }

            epsg = CRS.lookupEpsgCode(crs, true);
          } catch (FactoryException e) {
            LOGGER.log(Level.FINER, "Unable to look epsg code", e);
          }

          StringBuffer sql = new StringBuffer();
          sql.append("CALL AddGeometryColumn(");
          if (schemaName != null) {
            sql.append("'").append(schemaName).append("'");
          } else {
            sql.append("NULL");
          }
          sql.append(", '").append(tableName).append("'");
          sql.append(", '").append(gd.getLocalName()).append("'");
          sql.append(", ").append(epsg);
          sql.append(", '").append(Geometries.getForBinding(binding).getName()).append("'");
          sql.append(", ").append(2); // TODO: dimension
          sql.append(")");

          LOGGER.fine(sql.toString());
          st.execute(sql.toString());

          if (epsg != -1) {
            sql = new StringBuffer();
            sql.append("CALL CreateSpatialIndex(");
            if (schemaName == null) {
              sql.append("NULL");
            } else {
              sql.append("'").append(schemaName).append("'");
            }

            sql.append(",'").append(tableName).append("'");
            sql.append(",'").append(propertyName).append("'");
            sql.append(",'").append(epsg).append("')");

            LOGGER.fine(sql.toString());
            st.execute(sql.toString());
          }
        }
      }
    } finally {
      dataStore.closeSafe(st);
    }
  }
Example #30
0
  /** Creates GEOMETRY_COLUMN registrations and spatial indexes for all geometry columns */
  @Override
  public void postCreateTable(String schemaName, SimpleFeatureType featureType, Connection cx)
      throws SQLException {
    schemaName = schemaName != null ? schemaName : "public";
    String tableName = featureType.getName().getLocalPart();

    Statement st = null;
    try {
      st = cx.createStatement();

      // register all geometry columns in the database
      for (AttributeDescriptor att : featureType.getAttributeDescriptors()) {
        if (att instanceof GeometryDescriptor) {
          GeometryDescriptor gd = (GeometryDescriptor) att;

          // lookup or reverse engineer the srid
          int srid = -1;
          if (gd.getUserData().get(JDBCDataStore.JDBC_NATIVE_SRID) != null) {
            srid = (Integer) gd.getUserData().get(JDBCDataStore.JDBC_NATIVE_SRID);
          } else if (gd.getCoordinateReferenceSystem() != null) {
            try {
              Integer result = CRS.lookupEpsgCode(gd.getCoordinateReferenceSystem(), true);
              if (result != null) srid = result;
            } catch (Exception e) {
              LOGGER.log(
                  Level.FINE,
                  "Error looking up the " + "epsg code for metadata " + "insertion, assuming -1",
                  e);
            }
          }

          // assume 2 dimensions, but ease future customisation
          int dimensions = 2;

          // grab the geometry type
          String geomType = CLASS_TO_TYPE_MAP.get(gd.getType().getBinding());
          if (geomType == null) geomType = "GEOMETRY";

          String sql = null;
          if (getVersion(cx).compareTo(V_2_0_0) >= 0) {
            // postgis 2 and up we don't muck with geometry_columns, we just alter the
            // type directly to set the geometry type and srid
            // setup the geometry type
            sql =
                "ALTER TABLE \""
                    + schemaName
                    + "\".\""
                    + tableName
                    + "\" "
                    + "ALTER COLUMN \""
                    + gd.getLocalName()
                    + "\" "
                    + "TYPE geometry ("
                    + geomType
                    + ", "
                    + srid
                    + ");";

            LOGGER.fine(sql);
            st.execute(sql);
          } else {
            // register the geometry type, first remove and eventual
            // leftover, then write out the real one
            sql =
                "DELETE FROM GEOMETRY_COLUMNS"
                    + " WHERE f_table_catalog=''" //
                    + " AND f_table_schema = '"
                    + schemaName
                    + "'" //
                    + " AND f_table_name = '"
                    + tableName
                    + "'" //
                    + " AND f_geometry_column = '"
                    + gd.getLocalName()
                    + "'";

            LOGGER.fine(sql);
            st.execute(sql);

            sql =
                "INSERT INTO GEOMETRY_COLUMNS VALUES (''," //
                    + "'"
                    + schemaName
                    + "'," //
                    + "'"
                    + tableName
                    + "'," //
                    + "'"
                    + gd.getLocalName()
                    + "'," //
                    + dimensions
                    + "," //
                    + srid
                    + "," //
                    + "'"
                    + geomType
                    + "')";
            LOGGER.fine(sql);
            st.execute(sql);
          }

          // add srid checks
          if (srid > -1) {
            sql =
                "ALTER TABLE " //
                    + "\""
                    + schemaName
                    + "\"" //
                    + "." //
                    + "\""
                    + tableName
                    + "\"" //
                    + " ADD CONSTRAINT \"enforce_srid_" //
                    + gd.getLocalName()
                    + "\"" //
                    + " CHECK (ST_SRID(" //
                    + "\""
                    + gd.getLocalName()
                    + "\"" //
                    + ") = "
                    + srid
                    + ")";
            LOGGER.fine(sql);
            st.execute(sql);
          }

          // add dimension checks
          sql =
              "ALTER TABLE " //
                  + "\""
                  + schemaName
                  + "\"" //
                  + "." //
                  + "\""
                  + tableName
                  + "\"" //
                  + " ADD CONSTRAINT \"enforce_dims_" //
                  + gd.getLocalName()
                  + "\"" //
                  + " CHECK (st_ndims(\""
                  + gd.getLocalName()
                  + "\")" //
                  + " = 2)";
          LOGGER.fine(sql);
          st.execute(sql);

          // add geometry type checks
          if (!geomType.equals("GEOMETRY")) {
            sql =
                "ALTER TABLE " //
                    + "\""
                    + schemaName
                    + "\"" //
                    + "." //
                    + "\""
                    + tableName
                    + "\"" //
                    + " ADD CONSTRAINT \"enforce_geotype_" //
                    + gd.getLocalName()
                    + "\"" //
                    + " CHECK (geometrytype(" //
                    + "\""
                    + gd.getLocalName()
                    + "\"" //
                    + ") = '"
                    + geomType
                    + "'::text "
                    + "OR \""
                    + gd.getLocalName()
                    + "\"" //
                    + " IS NULL)";
            LOGGER.fine(sql);
            st.execute(sql);
          }

          // add the spatial index
          sql =
              "CREATE INDEX \"spatial_"
                  + tableName //
                  + "_"
                  + gd.getLocalName().toLowerCase()
                  + "\"" //
                  + " ON " //
                  + "\""
                  + schemaName
                  + "\"" //
                  + "." //
                  + "\""
                  + tableName
                  + "\"" //
                  + " USING GIST (" //
                  + "\""
                  + gd.getLocalName()
                  + "\"" //
                  + ")";
          LOGGER.fine(sql);
          st.execute(sql);
        }
      }
      if (!cx.getAutoCommit()) {
        cx.commit();
      }
    } finally {
      dataStore.closeSafe(st);
    }
  }