|
From: <svn...@os...> - 2012-01-15 18:25:31
|
Author: aaime Date: 2012-01-15 10:25:20 -0800 (Sun, 15 Jan 2012) New Revision: 38482 Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureTypeMapper.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FilterToRestrictedWhere.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureStore.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFilterTranslator.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRUtils.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/CplErrorLibrary.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/OGREnvelope.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/OGRField.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/OgrLibrary.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/OsrLibrary.java branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/__locale_struct.java Log: Whoops, forgot to commit some files Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureTypeMapper.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureTypeMapper.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FeatureTypeMapper.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,376 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import static org.bridj.Pointer.*; +import static org.geotools.data.ogr.bridj.OgrLibrary.*; +import static org.geotools.data.ogr.bridj.OsrLibrary.*; + +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; + +import org.bridj.Pointer; +import org.bridj.ValuedEnum; +import org.geotools.data.ogr.bridj.OgrLibrary.OGRFieldType; +import org.geotools.data.ogr.bridj.OgrLibrary.OGRJustification; +import org.geotools.data.ogr.bridj.OgrLibrary.OGRwkbGeometryType; +import org.geotools.feature.FeatureTypes; +import org.geotools.feature.simple.SimpleFeatureTypeBuilder; +import org.geotools.feature.type.BasicFeatureTypes; +import org.geotools.referencing.CRS; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.feature.type.GeometryDescriptor; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryCollection; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.LinearRing; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPoint; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.geom.Polygon; + +/** + * Helper mapping between geotools and OGR feature types + * + * @author Andrea Aime - GeoSolutions + */ +class FeatureTypeMapper { + + /** + * Returns the geotools feature type equivalent from the native OGR one + * + * @param layer + * @param typeName + * @param namespaceURI + * @return + * @throws IOException + */ + SimpleFeatureType getFeatureType(Pointer layer, String typeName, String namespaceURI) + throws IOException { + Pointer definition = null; + try { + // setup the builder + SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); + tb.setName(typeName); + tb.setNamespaceURI(namespaceURI); + if (tb.getNamespaceURI() == null) { + tb.setNamespaceURI(BasicFeatureTypes.DEFAULT_NAMESPACE); + } + + // grab the layer definition + definition = OGR_L_GetLayerDefn(layer); + + // figure out the geometry + Class<? extends Geometry> geometryBinding = getGeometryBinding(definition); + if (geometryBinding != null) { + CoordinateReferenceSystem crs = getCRS(layer); + tb.add("the_geom", geometryBinding, crs); + } + + // get the non geometric fields + final int count = OGR_FD_GetFieldCount(definition); + for (int i = 0; i < count; i++) { + Pointer field = OGR_FD_GetFieldDefn(definition, i); + String name = OGR_Fld_GetNameRef(field).getCString(); + Class binding = getBinding(field); + int width = OGR_Fld_GetWidth(field); + if (width > 0) { + tb.length(width); + } + tb.add(name, binding); + } + + // compute a default parent feature type + if ((geometryBinding == Point.class) || (geometryBinding == MultiPoint.class)) { + tb.setSuperType(BasicFeatureTypes.POINT); + } else if ((geometryBinding == Polygon.class) + || (geometryBinding == MultiPolygon.class)) { + tb.setSuperType(BasicFeatureTypes.POLYGON); + } else if ((geometryBinding == LineString.class) + || (geometryBinding == MultiLineString.class)) { + tb.setSuperType(BasicFeatureTypes.LINE); + } + + return tb.buildFeatureType(); + } finally { + OGRUtils.releaseDefinition(definition); + } + } + + /** + * Maps the OGR field type to a java class + * + * @param field + * @return + */ + private Class getBinding(Pointer field) { + ValuedEnum<OGRFieldType> type = OGR_Fld_GetType(field); + int width = OGR_Fld_GetWidth(field); + long value = type.value(); + if (value == OGRFieldType.OFTInteger.value()) { + if (width <= 3) { + return Byte.class; + } else if (width <= 5) { + return Short.class; + } else if (width <= 9) { + return Integer.class; + } else if (width <= 19) { + return Long.class; + } else { + return BigDecimal.class; + } + } else if (value == OGRFieldType.OFTIntegerList.value()) { + return int[].class; + } else if (value == OGRFieldType.OFTReal.value()) { + if (width <= 12) { + return Float.class; + } else if (width <= 22) { + return Double.class; + } else { + return BigDecimal.class; + } + } else if (value == OGRFieldType.OFTRealList.value()) { + return double[].class; + } else if (value == OGRFieldType.OFTBinary.value()) { + return byte[].class; + } else if (value == OGRFieldType.OFTDate.value()) { + return java.sql.Date.class; + } else if (value == OGRFieldType.OFTTime.value()) { + return java.sql.Time.class; + } else if (value == OGRFieldType.OFTDateTime.value()) { + return java.sql.Timestamp.class; + } else { + // whatever else we'll map a string + return String.class; + } + } + + /** + * Returns a OGR field definition compatible with the specified attribute descriptor where: + * <ul> + * <li>width is the number of chars needed to format the strings equivalent of the number + * <li> + * <li>precision is the number of chars after decimal pont</li> + * <li>justification: right or left (in outputs)</li> + * </ul> + * + * @param ad + * @throws IOException + */ + public Pointer getOGRFieldDefinition(AttributeDescriptor ad) throws IOException { + final Class type = ad.getType().getBinding(); + final Pointer def; + Pointer<Byte> namePtr = pointerToCString(ad.getLocalName()); + if (Boolean.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTString); + OGR_Fld_SetWidth(def, 5); + } else if (Byte.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 3); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Short.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 5); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Integer.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 9); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Long.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 19); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (BigInteger.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 32); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (BigDecimal.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTReal); + OGR_Fld_SetWidth(def, 32); + OGR_Fld_SetPrecision(def, 15); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Float.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTReal); + OGR_Fld_SetWidth(def, 12); + OGR_Fld_SetPrecision(def, 7); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (Double.class.equals(type) || Number.class.isAssignableFrom(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTInteger); + OGR_Fld_SetWidth(def, 22); + OGR_Fld_SetPrecision(def, 16); + OGR_Fld_SetJustify(def, OGRJustification.OJRight); + } else if (String.class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTString); + int length = FeatureTypes.getFieldLength(ad); + if (length <= 0) { + length = 255; + } + OGR_Fld_SetWidth(def, length); + } else if (byte[].class.equals(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTBinary); + } else if (java.sql.Date.class.isAssignableFrom(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTDate); + } else if (java.sql.Time.class.isAssignableFrom(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTTime); + } else if (java.util.Date.class.isAssignableFrom(type)) { + def = OGR_Fld_Create(namePtr, OGRFieldType.OFTDateTime); + } else { + throw new IOException("Cannot map " + type + " to an OGR type"); + } + + return def; + } + + /** + * Returns the OGR geometry type constant given a geometry attribute type + * + * @param descriptor + * @return + * @throws IOException + */ + public ValuedEnum<OGRwkbGeometryType> getOGRGeometryType(GeometryDescriptor descriptor) + throws IOException { + Class binding = descriptor.getType().getBinding(); + if (GeometryCollection.class.isAssignableFrom(binding)) { + if (MultiPoint.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbMultiPoint; + } else if (MultiLineString.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbMultiLineString; + } else if (MultiPolygon.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbMultiPolygon; + } else { + return OGRwkbGeometryType.wkbGeometryCollection; + } + } else { + if (Point.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbPoint; + } else if (LinearRing.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbLinearRing; + } else if (LineString.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbLineString; + } else if (Polygon.class.isAssignableFrom(binding)) { + return OGRwkbGeometryType.wkbPolygon; + } else { + return OGRwkbGeometryType.wkbUnknown; + } + } + } + + /** + * Returns the JTS geometry type equivalent to the layer native one + * + * @param definition + * @return + * @throws IOException + */ + private Class<? extends Geometry> getGeometryBinding(Pointer definition) throws IOException { + ValuedEnum<OGRwkbGeometryType> gt = OGR_FD_GetGeomType(definition); + long value = gt.value(); + // for line and polygon we return multi in any case since OGR will declare simple for + // multigeom + // anyways and then return simple or multi in the actual geoemtries depending on + // what it finds + if (value == OGRwkbGeometryType.wkbPoint.value() + || value == OGRwkbGeometryType.wkbPoint25D.value()) { + return Point.class; + } else if (value == OGRwkbGeometryType.wkbLinearRing.value()) { + return LinearRing.class; + } else if (value == OGRwkbGeometryType.wkbLineString.value() + || value == OGRwkbGeometryType.wkbLineString25D.value() + || value == OGRwkbGeometryType.wkbMultiLineString.value() + || value == OGRwkbGeometryType.wkbMultiLineString25D.value()) { + return MultiLineString.class; + } else if (value == OGRwkbGeometryType.wkbPolygon.value() + || value == OGRwkbGeometryType.wkbPolygon25D.value() + || value == OGRwkbGeometryType.wkbMultiPolygon.value() + || value == OGRwkbGeometryType.wkbMultiPolygon25D.value()) { + return MultiPolygon.class; + } else if (value == OGRwkbGeometryType.wkbGeometryCollection.value() + || value == OGRwkbGeometryType.wkbGeometryCollection25D.value()) { + return GeometryCollection.class; + } else if (value == OGRwkbGeometryType.wkbNone.value()) { + return null; + } else if (value == OGRwkbGeometryType.wkbUnknown.value()) { + return Geometry.class; + } else { + throw new IOException("Unknown geometry type: " + value); + } + } + + /** + * Returns the GeoTools {@link CoordinateReferenceSystem} equivalent to the layer native one + * + * @param layer + * @return + * @throws IOException + */ + private CoordinateReferenceSystem getCRS(Pointer layer) throws IOException { + Pointer spatialReference = null; + CoordinateReferenceSystem crs = null; + try { + spatialReference = OGR_L_GetSpatialRef(layer); + if (spatialReference == null) { + return null; + } + + try { + Pointer<Byte> code = OSRGetAuthorityCode(spatialReference, pointerToCString("EPSG")); + if (code != null) { + String fullCode = "EPSG:" + code; + crs = CRS.decode(fullCode); + } + } catch (Exception e) { + // fine, the code might be unknown to out authority + } + if (crs == null) { + try { + Pointer<Pointer<Byte>> wktPtr = allocatePointer(Byte.class); + OSRExportToWkt(spatialReference, wktPtr); + String wkt = wktPtr.getPointer(Byte.class).getCString(); + crs = CRS.parseWKT(wkt); + } catch (Exception e) { + // the wkt might reference an unsupported projection + } + } + return crs; + } finally { + OGRUtils.releaseSpatialReference(spatialReference); + } + } + + /** + * Returns a Pointer to a OGR spatial reference object equivalent to the specified GeoTools CRS + * + * @param crs + * @return + */ + public Pointer getSpatialReference(CoordinateReferenceSystem crs) { + if (crs == null) { + return null; + } + + // use tostring to get a lenient wkt translation + String wkt = crs.toString(); + return OSRNewSpatialReference(pointerToCString(wkt)); + } + +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FilterToRestrictedWhere.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FilterToRestrictedWhere.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/FilterToRestrictedWhere.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,429 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Iterator; + +import org.geotools.factory.Hints; +import org.geotools.util.ConverterFactory; +import org.geotools.util.Converters; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.AttributeDescriptor; +import org.opengis.filter.And; +import org.opengis.filter.BinaryComparisonOperator; +import org.opengis.filter.BinaryLogicOperator; +import org.opengis.filter.ExcludeFilter; +import org.opengis.filter.Filter; +import org.opengis.filter.FilterVisitor; +import org.opengis.filter.Id; +import org.opengis.filter.IncludeFilter; +import org.opengis.filter.Not; +import org.opengis.filter.Or; +import org.opengis.filter.PropertyIsBetween; +import org.opengis.filter.PropertyIsEqualTo; +import org.opengis.filter.PropertyIsGreaterThan; +import org.opengis.filter.PropertyIsGreaterThanOrEqualTo; +import org.opengis.filter.PropertyIsLessThan; +import org.opengis.filter.PropertyIsLessThanOrEqualTo; +import org.opengis.filter.PropertyIsLike; +import org.opengis.filter.PropertyIsNotEqualTo; +import org.opengis.filter.PropertyIsNull; +import org.opengis.filter.expression.Add; +import org.opengis.filter.expression.Divide; +import org.opengis.filter.expression.Expression; +import org.opengis.filter.expression.ExpressionVisitor; +import org.opengis.filter.expression.Function; +import org.opengis.filter.expression.Literal; +import org.opengis.filter.expression.Multiply; +import org.opengis.filter.expression.NilExpression; +import org.opengis.filter.expression.PropertyName; +import org.opengis.filter.expression.Subtract; +import org.opengis.filter.spatial.BBOX; +import org.opengis.filter.spatial.Beyond; +import org.opengis.filter.spatial.Contains; +import org.opengis.filter.spatial.Crosses; +import org.opengis.filter.spatial.DWithin; +import org.opengis.filter.spatial.Disjoint; +import org.opengis.filter.spatial.Equals; +import org.opengis.filter.spatial.Intersects; +import org.opengis.filter.spatial.Overlaps; +import org.opengis.filter.spatial.Touches; +import org.opengis.filter.spatial.Within; + +/** + * Encodes a compliant filter to the "restricted where" syntax supported by OGR: + * + * <pre> + * @condition@ = @field_name@ @binary_operator@ @value@ | "(" @condition@ ")" @binary_logical_operator@ + * "(" @condition@ ")" + * @binary_operator@ = "<" | ">" | "<=" | ">=" | "<>" | "=" + * @binary_logical_operator@ = "AND" | "OR" + * @field_name@ = @string_token@ + * @value@ = @string_token@ | @numeric_value@ | @string_value@ + * @string_value@ = "'" @characters@ "'" + * </pre> + * + * Implementation wise this is a widely cut down version of JDBC's module FilterToSQL + * + * @author Andrea Aime - GeoSolutions + */ +class FilterToRestrictedWhere implements FilterVisitor, ExpressionVisitor { + /** error message for exceptions */ + protected static final String IO_ERROR = "io problem writing filter"; + + /** the schema the encoder will be used to be encode sql for */ + protected SimpleFeatureType featureType; + + StringWriter out = new StringWriter(); + + public FilterToRestrictedWhere(SimpleFeatureType featureType) { + this.featureType = featureType; + } + + public String getRestrictedWhere() { + return out.toString(); + } + + /** + * Writes the SQL for the PropertyIsBetween Filter. + * + * @param filter the Filter to be visited. + * + * @throws RuntimeException for io exception with writer + */ + public Object visit(PropertyIsBetween filter, Object extraData) throws RuntimeException { + Expression expr = (Expression) filter.getExpression(); + Expression lowerbounds = (Expression) filter.getLowerBoundary(); + Expression upperbounds = (Expression) filter.getUpperBoundary(); + + Class context; + AttributeDescriptor attType = (AttributeDescriptor) expr.evaluate(featureType); + if (attType != null) { + context = attType.getType().getBinding(); + } else { + context = String.class; + } + + out.write("(("); + expr.accept(this, extraData); + out.write(">="); + lowerbounds.accept(this, context); + out.write(") AND ("); + expr.accept(this, extraData); + out.write("<="); + upperbounds.accept(this, context); + out.write("))"); + + return extraData; + } + + /** + * Write the SQL for an And filter + * + * @param filter the filter to visit + * @param extraData extra data (unused by this method) + * + */ + public Object visit(And filter, Object extraData) { + return visit((BinaryLogicOperator) filter, "AND"); + } + + /** + * Write the SQL for an Or filter + * + * @param filter the filter to visit + * @param extraData extra data (unused by this method) + * + */ + public Object visit(Or filter, Object extraData) { + return visit((BinaryLogicOperator) filter, "OR"); + } + + /** + * Common implementation for BinaryLogicOperator filters. This way they're all handled + * centrally. + * + * @param filter the logic statement to be turned into SQL. + * @param extraData extra filter data. Not modified directly by this method. + */ + protected Object visit(BinaryLogicOperator filter, Object extraData) { + String type = (String) extraData; + out.write("("); + + Iterator<Filter> list = filter.getChildren().iterator(); + while (list.hasNext()) { + list.next().accept(this, extraData); + + if (list.hasNext()) { + out.write(" " + type + " "); + } + } + out.write(")"); + return extraData; + } + + public Object visit(PropertyIsEqualTo filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, "="); + return extraData; + } + + public Object visit(PropertyIsGreaterThanOrEqualTo filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, ">="); + return extraData; + } + + public Object visit(PropertyIsGreaterThan filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, ">"); + return extraData; + } + + public Object visit(PropertyIsLessThan filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, "<"); + return extraData; + } + + public Object visit(PropertyIsLessThanOrEqualTo filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, "<="); + return extraData; + } + + public Object visit(PropertyIsNotEqualTo filter, Object extraData) { + visitBinaryComparisonOperator((BinaryComparisonOperator) filter, "!="); + return extraData; + } + + protected void visitBinaryComparisonOperator(BinaryComparisonOperator filter, Object extraData) + throws RuntimeException { + Expression left = filter.getExpression1(); + Expression right = filter.getExpression2(); + + // see if we can get some indication on how to evaluate literals + Class leftContext = null, rightContext = null; + if (left instanceof PropertyName) { + AttributeDescriptor attType = (AttributeDescriptor) left.evaluate(featureType); + if (attType != null) { + rightContext = attType.getType().getBinding(); + } + } + if (rightContext == null && right instanceof PropertyName) { + AttributeDescriptor attType = (AttributeDescriptor) right.evaluate(featureType); + if (attType != null) { + leftContext = attType.getType().getBinding(); + } + } + + String type = (String) extraData; + left.accept(this, leftContext); + out.write(" " + type + " "); + right.accept(this, rightContext); + } + + public Object visit(PropertyName expression, Object extraData) throws RuntimeException { + AttributeDescriptor attribute = null; + try { + attribute = (AttributeDescriptor) expression.evaluate(featureType); + } catch (Exception e) { + // just log and fall back on just encoding propertyName straight up + String msg = "Error occured mapping " + expression + " to feature type"; + } + String name = null; + if (attribute != null) { + name = attribute.getLocalName(); + } else { + name = expression.getPropertyName(); + } + out.write(name); + + return extraData; + } + + /** + * Export the contents of a Literal Expresion + * + * @param expression the Literal to export + * + * @throws RuntimeException for io exception with writer + */ + public Object visit(Literal expression, Object context) throws RuntimeException { + // type to convert the literal to + Class target = null; + if (context instanceof Class) { + target = (Class) context; + } + + // evaluate the expression + Object literal = evaluateLiteral(expression, target); + writeLiteral(literal); + return context; + } + + protected Object evaluateLiteral(Literal expression, Class target) { + Object literal = null; + + // HACK: let expression figure out the right value for numbers, + // since the context is almost always improperly set and the + // numeric converters try to force floating points to integrals + // JD: the above is no longer true, so instead do a safe conversion + if (target != null) { + // use the target type + if (Number.class.isAssignableFrom(target)) { + literal = Converters.convert(expression.evaluate(null), target, new Hints( + ConverterFactory.SAFE_CONVERSION, true)); + } else { + literal = expression.evaluate(null, target); + } + } + // if the target was not known, of the conversion failed, try the + // type guessing dance literal expression does only for the following + // method call + if (literal == null) + literal = expression.evaluate(null); + + // if that failed as well, grab the value as is + if (literal == null) + literal = expression.getValue(); + + return literal; + } + + /** + * Writes out a non null, non geometry literal. The base class properly handles null, numeric + * and booleans (true|false), and turns everything else into a string. Subclasses are expected + * to override this shall they need a different treatment (e.g. for dates) + * + * @param literal + * @throws IOException + */ + protected void writeLiteral(Object literal) { + if (literal == null) { + out.write("NULL"); + } else if (literal instanceof Number || literal instanceof Boolean) { + out.write(String.valueOf(literal)); + } else { + // we don't know what this is, let's convert back to a string + String encoding = (String) Converters.convert(literal, String.class, null); + if (encoding == null) { + // could not convert back to string, use original l value + encoding = literal.toString(); + } + + // sigle quotes must be escaped to have a valid sql string + String escaped = encoding.replaceAll("'", "''"); + out.write("'" + escaped + "'"); + } + } + + public Object visit(NilExpression expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Add expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Divide expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Function expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Multiply expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Subtract expression, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visitNullFilter(Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(ExcludeFilter filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(IncludeFilter filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Id filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Not filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(PropertyIsLike filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(PropertyIsNull filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(BBOX filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Beyond filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Contains filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Crosses filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Disjoint filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(DWithin filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Equals filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Intersects filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Overlaps filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Touches filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + public Object visit(Within filter, Object extraData) { + throw new UnsupportedOperationException(); + } + + + } Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,96 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import org.bridj.BridJ; +import org.geotools.data.ogr.bridj.OgrLibrary; + +/** + * Helper class allowing to locate the GDAL library and attach to it + * + * @source $URL: https://svn.osgeo.org/geotools/trunk/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/GdalInit.java $ + */ +class GdalInit { + + private static volatile String NATIVE_NAME; + + public static void init() { + if (NATIVE_NAME == null) { + synchronized (GdalInit.class) { + if (NATIVE_NAME == null) { + NATIVE_NAME = System.getProperty("GDAL_LIBRARY_NAME"); + if(NATIVE_NAME != null) { + // someone told us its name + if(!checkNativeName(NATIVE_NAME)) { + throw new RuntimeException( + "Failed to bind to user specified gdal library named: " + NATIVE_NAME); + } + } else { + // on linux platforms libgdal is normally associated with its version, + // painful... + // generate a bunch of the known release numbers, plus more for the future + // :) + if (!checkNativeName("gdal") && !(checkNativeName("gdal_fw"))) { + int x = 1; + // for (int x = 2; x >= 1; x--) { + for (int y = 10; y >= 0; y--) { + if (checkNativeName("gdal" + x + "." + y)) { + return; + } + for (int z = 5; z >= 0; z--) { + if (checkNativeName("gdal" + x + "." + y + "." + z)) { + return; + } + } + } + // } + throw new RuntimeException( + "Failed to automatically guess the gdal library name, please set the GDAL_LIBRARY_NAME system variable"); + } + } + } + } + } + } + + static boolean checkNativeName(String name) { + try { + if (BridJ.getNativeLibrary(name) != null) { + registerAlias(name); + OgrLibrary.OGRGetDriverCount(); + + NATIVE_NAME = name; + + return true; + } else { + return false; + } + } catch (Throwable t) { + return false; + } + } + + private static void registerAlias(String name) { + System.out.println("Registered library as " + name); + BridJ.addNativeLibraryAlias("ogr", name); + BridJ.addNativeLibraryAlias("osr", name); + BridJ.addNativeLibraryAlias("cplError", name); + BridJ.addNativeLibraryAlias("gdal", name); + } + + +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureStore.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureStore.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFeatureStore.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,166 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import java.io.IOException; + +import org.bridj.Pointer; +import org.geotools.data.FeatureReader; +import org.geotools.data.FeatureWriter; +import org.geotools.data.Query; +import org.geotools.data.QueryCapabilities; +import org.geotools.data.ResourceInfo; +import org.geotools.data.Transaction; +import org.geotools.data.store.ContentEntry; +import org.geotools.data.store.ContentFeatureStore; +import org.geotools.data.store.ContentState; +import org.geotools.geometry.jts.ReferencedEnvelope; +import org.opengis.feature.FeatureVisitor; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.feature.type.Name; + +import com.vividsolutions.jts.geom.GeometryFactory; + +/** + * FeatureStore for the OGR store, based on the {@link ContentFeatureStore} framework + * + * @author Andrea Aime - GeoSolutions + */ +@SuppressWarnings("rawtypes") +class OGRFeatureStore extends ContentFeatureStore { + + OGRFeatureSource delegate; + + public OGRFeatureStore(ContentEntry entry, Query query) { + super(entry, query); + delegate = new OGRFeatureSource(entry, query); + } + + @Override + protected FeatureWriter<SimpleFeatureType, SimpleFeature> getWriterInternal(Query query, + int flags) throws IOException { + Pointer dataSource = null; + Pointer layer = null; + boolean cleanup = true; + try { + // grab the layer + String typeName = getEntry().getTypeName(); + dataSource = getDataStore().openOGRDataSource(true); + layer = getDataStore().openOGRLayer(dataSource, typeName); + + FeatureReader<SimpleFeatureType, SimpleFeature> reader = delegate.getReaderInternal( + dataSource, layer, query); + GeometryFactory gf = delegate.getGeometryFactory(query); + OGRDirectFeatureWriter result = new OGRDirectFeatureWriter(dataSource, layer, reader, + getSchema(), gf); + cleanup = false; + return result; + } finally { + if (cleanup) { + OGRUtils.releaseLayer(layer); + OGRUtils.releaseDataSource(dataSource); + } + } + } + + // ---------------------------------------------------------------------------------------- + // METHODS DELEGATED TO OGRFeatureSource + // ---------------------------------------------------------------------------------------- + + public OGRDataStore getDataStore() { + return delegate.getDataStore(); + } + + public Transaction getTransaction() { + return delegate.getTransaction(); + } + + public ResourceInfo getInfo() { + return delegate.getInfo(); + } + + public QueryCapabilities getQueryCapabilities() { + return delegate.getQueryCapabilities(); + } + + @Override + protected ReferencedEnvelope getBoundsInternal(Query query) throws IOException { + return delegate.getBoundsInternal(query); + } + + @Override + protected int getCountInternal(Query query) throws IOException { + return delegate.getCountInternal(query); + } + + @Override + protected FeatureReader<SimpleFeatureType, SimpleFeature> getReaderInternal(Query query) + throws IOException { + return delegate.getReaderInternal(query); + } + + @Override + protected SimpleFeatureType buildFeatureType() throws IOException { + return delegate.buildFeatureType(); + } + + @Override + public ContentEntry getEntry() { + return delegate.getEntry(); + } + + @Override + public Name getName() { + return delegate.getName(); + } + + @Override + public ContentState getState() { + return delegate.getState(); + } + + @Override + public void setTransaction(Transaction transaction) { + super.setTransaction(transaction); + + if (delegate.getTransaction() != transaction) { + delegate.setTransaction(transaction); + } + } + + @Override + protected boolean canFilter() { + return delegate.canFilter(); + } + + @Override + protected boolean canSort() { + return delegate.canSort(); + } + + @Override + protected boolean canRetype() { + return delegate.canRetype(); + } + + @Override + protected boolean handleVisitor(Query query, FeatureVisitor visitor) throws IOException { + return delegate.handleVisitor(query, visitor); + } + +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFilterTranslator.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFilterTranslator.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRFilterTranslator.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,214 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import org.geotools.filter.FilterCapabilities; +import org.geotools.filter.visitor.PostPreProcessFilterSplittingVisitor; +import org.geotools.filter.visitor.SimplifyingFilterVisitor; +import org.opengis.feature.simple.SimpleFeatureType; +import org.opengis.filter.And; +import org.opengis.filter.Filter; +import org.opengis.filter.Or; +import org.opengis.filter.PropertyIsBetween; +import org.opengis.filter.PropertyIsEqualTo; +import org.opengis.filter.PropertyIsGreaterThan; +import org.opengis.filter.PropertyIsGreaterThanOrEqualTo; +import org.opengis.filter.PropertyIsLessThan; +import org.opengis.filter.PropertyIsLessThanOrEqualTo; +import org.opengis.filter.PropertyIsNotEqualTo; +import org.opengis.filter.expression.Expression; +import org.opengis.filter.expression.Literal; +import org.opengis.filter.expression.PropertyName; +import org.opengis.filter.spatial.BBOX; +import org.opengis.filter.spatial.BinarySpatialOperator; +import org.opengis.filter.spatial.Contains; +import org.opengis.filter.spatial.Crosses; +import org.opengis.filter.spatial.Equals; +import org.opengis.filter.spatial.Intersects; +import org.opengis.filter.spatial.Overlaps; +import org.opengis.filter.spatial.Touches; +import org.opengis.filter.spatial.Within; + +import com.vividsolutions.jts.geom.Geometry; + +/** + * Helper which translates the GeoTools filters into the filter bits that OGR understands + * + * @author Andrea Aime - GeoSolutions + */ +class OGRFilterTranslator { + + static final FilterCapabilities ATTRIBUTE_FILTER_CAPABILITIES; + + static final FilterCapabilities GEOMETRY_FILTER_CAPABILITIES; + + static final FilterCapabilities STRICT_GEOMETRY_FILTER_CAPABILITIES; + + static final FilterCapabilities EXTENDED_FILTER_CAPABILITIES; + + static { + // attribute filters, these we can encode fully + ATTRIBUTE_FILTER_CAPABILITIES = new FilterCapabilities(); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsBetween.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsNotEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsGreaterThan.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsLessThan.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsGreaterThanOrEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsLessThanOrEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(PropertyIsLessThanOrEqualTo.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(Or.class); + ATTRIBUTE_FILTER_CAPABILITIES.addType(And.class); + + // we cannot encode these full, but have the capabilities extract + // any filter that can use geometric intersection as its base (bbox is the only + // one that we're sure to get support for) + GEOMETRY_FILTER_CAPABILITIES = new FilterCapabilities(); + GEOMETRY_FILTER_CAPABILITIES.addType(BBOX.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Contains.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Crosses.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Equals.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Intersects.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Overlaps.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Touches.class); + GEOMETRY_FILTER_CAPABILITIES.addType(Within.class); + + // the geometry filters we can encode 1-1 + STRICT_GEOMETRY_FILTER_CAPABILITIES = new FilterCapabilities(); + STRICT_GEOMETRY_FILTER_CAPABILITIES.addType(BBOX.class); + + // the extended caps, which work only assuming there is at most a single bbox filter + // in the filter to be encoded + EXTENDED_FILTER_CAPABILITIES = new FilterCapabilities(); + EXTENDED_FILTER_CAPABILITIES.addAll(ATTRIBUTE_FILTER_CAPABILITIES); + EXTENDED_FILTER_CAPABILITIES.addAll(STRICT_GEOMETRY_FILTER_CAPABILITIES); + } + + private SimpleFeatureType schema; + + private Filter filter; + + public OGRFilterTranslator(SimpleFeatureType schema, Filter filter) { + this.schema = schema; + SimplifyingFilterVisitor simplifier = new SimplifyingFilterVisitor(); + this.filter = (Filter) filter.accept(simplifier, null); + } + + /** + * Returns true if this filter can be fully encoded without requiring further post processing + * + * @return + */ + public boolean isFilterFullySupported() { + if (filter == Filter.INCLUDE || filter == Filter.EXCLUDE) { + return true; + } + + // we can encode fully an attribute filter plus a bbox spatial filter + PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor( + ATTRIBUTE_FILTER_CAPABILITIES, schema, null); + filter.accept(visitor, null); + Filter postFilter = visitor.getFilterPost(); + return postFilter == Filter.INCLUDE || postFilter instanceof BBOX; + } + + /** + * Returns the post filter that could not be encoded + * + * @return + */ + public Filter getPostFilter() { + // see if the query has a single bbox filter (that's how much we're sure to be able to + // encode) + PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor( + STRICT_GEOMETRY_FILTER_CAPABILITIES, schema, null); + filter.accept(visitor, null); + Filter preFilter = visitor.getFilterPre(); + + if (preFilter == null || preFilter instanceof BBOX) { + // ok, then we can extract using the extended caps + visitor = new PostPreProcessFilterSplittingVisitor(EXTENDED_FILTER_CAPABILITIES, + schema, null); + filter.accept(visitor, null); + return visitor.getFilterPost(); + } else { + // though luck, there is more than a single bbox filter + visitor = new PostPreProcessFilterSplittingVisitor(ATTRIBUTE_FILTER_CAPABILITIES, + schema, null); + filter.accept(visitor, null); + return visitor.getFilterPost(); + } + } + + /** + * Parses the Geotools filter and tries to extract an intersecting geometry that can be used as + * the OGR spatial filter + * + * @param schema + * @param filter + * @return + */ + public Geometry getSpatialFilter() { + // TODO: switch to the non deprecated splitter (that no one seems to be using) + PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor( + GEOMETRY_FILTER_CAPABILITIES, schema, null); + filter.accept(visitor, null); + Filter preFilter = visitor.getFilterPre(); + if (preFilter instanceof BinarySpatialOperator) { + BinarySpatialOperator bso = ((BinarySpatialOperator) preFilter); + Expression geomExpression = null; + if (bso.getExpression1() instanceof PropertyName + && bso.getExpression2() instanceof Literal) { + geomExpression = bso.getExpression2(); + } else if (bso.getExpression1() instanceof Literal + && bso.getExpression2() instanceof PropertyName) { + geomExpression = bso.getExpression1(); + } + if (geomExpression != null) { + Geometry geom = geomExpression.evaluate(null, Geometry.class); + return geom; + } + } + return null; + } + + /** + * Parses the GeoTools filter and tries to extract an SQL expression that can be used as the OGR + * attribute filter + * + * @param schema + * @param filter + * @return + */ + public String getAttributeFilter() { + // TODO: switch to the non deprecated splitter (that no one seems to be using) + PostPreProcessFilterSplittingVisitor visitor = new PostPreProcessFilterSplittingVisitor( + ATTRIBUTE_FILTER_CAPABILITIES, schema, null); + filter.accept(visitor, null); + Filter preFilter = visitor.getFilterPre(); + if (preFilter != Filter.EXCLUDE && preFilter != Filter.INCLUDE) { + FilterToRestrictedWhere sqlConverter = new FilterToRestrictedWhere(schema); + preFilter.accept(sqlConverter, null); + return sqlConverter.getRestrictedWhere(); + } + return null; + } + + public Filter getFilter() { + return filter; + } +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRUtils.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRUtils.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/OGRUtils.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,129 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2007-2008, Open Source Geospatial Foundation (OSGeo) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License. + * + * This library 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 + * Lesser General Public License for more details. + */ +package org.geotools.data.ogr; + +import static org.geotools.data.ogr.bridj.OgrLibrary.*; +import static org.geotools.data.ogr.bridj.CplErrorLibrary.*; + +import java.io.IOException; + +import org.bridj.Pointer; + +/** + * Common utilities to deal with OGR pointers + * + * @author Andrea Aime - GeoSolutions + */ +@SuppressWarnings("rawtypes") +class OGRUtils { + + private static boolean HAS_L_GETNAME; + + public static void releaseDataSource(Pointer dataSet) { + if (dataSet != null) { + OGRReleaseDataSource(dataSet); + dataSet.release(); + } + } + + public static void releaseLayer(Pointer layer) { + if (layer != null) { + // OGR_L_Dereference(layer); + layer.release(); + } + + } + + public static void releaseDefinition(Pointer definition) { + if (definition != null) { + // OGR_FD_Destroy(definition); + definition.release(); + } + } + + public static void releaseSpatialReference(Pointer spatialReference) { + if (spatialReference != null) { + // OSRDestroySpatialReference(spatialReference); + spatialReference.release(); + } + } + + public static String getCString(Pointer<Byte> ptr) { + if(ptr == null) { + return null; + } else { + return ptr.getCString(); + } + } + + /** + * Gets a layer name in a version independent way + * @param layer + */ + public static String getLayerName(Pointer layer) { + Pointer<Byte> namePtr = null; + try { + // this one is more efficient but has been added recently + if(HAS_L_GETNAME) { + namePtr = OGR_L_GetName(layer); + } + } catch(Exception e) { + HAS_L_GETNAME = false; + } + if(namePtr == null) { + Pointer layerDefinition = OGR_L_GetLayerDefn(layer); + namePtr = OGR_FD_GetName(layerDefinition); + } + return getCString(namePtr); + } + + /** + * Checks the OGRErr status code and throws java exceptions accordingly + * + * @param ogrError + * @throws IOException + */ + public static void checkError(int ogrError) throws IOException { + if (ogrError == OGRERR_NONE) { + return; + } + + String error = getCString(CPLGetLastErrorMsg()); + + switch (ogrError) { + case OGRERR_CORRUPT_DATA: + throw new IOException("OGR reported a currupt data error: " + error); + case OGRERR_FAILURE: + throw new IOException("OGR reported a generic failure: " + error); + case OGRERR_INVALID_HANDLE: + throw new IOException("OGR reported an invalid handle error: " + error); + case OGRERR_NOT_ENOUGH_DATA: + throw new IOException("OGR reported not enough data was provided in the last call: " + error); + case OGRERR_NOT_ENOUGH_MEMORY: + throw new IOException("OGR reported not enough memory is available: " + error); + case OGRERR_UNSUPPORTED_GEOMETRY_TYPE: + throw new IOException("OGR reported a unsupported geometry type error: " + error); + case OGRERR_UNSUPPORTED_OPERATION: + throw new IOException("OGR reported a unsupported operation error: " + error); + case OGRERR_UNSUPPORTED_SRS: + throw new IOException("OGR reported a unsupported SRS error: " + error); + default: + throw new IOException("OGR reported an unrecognized error code: " + ogrError); + } + } + +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,19 @@ +package org.geotools.data.ogr.bridj; + +import org.bridj.Pointer; + +/** + * + * + * @source $URL: https://svn.osgeo.org/geotools/trunk/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/BridjUtilities.java $ + */ +public class BridjUtilities { + + public static String getCString(Pointer<?> ptr) { + if (ptr == null) { + return null; + } else { + return ptr.getCString(); + } + } +} Added: branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/CplErrorLibrary.java =================================================================== --- branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/CplErrorLibrary.java (rev 0) +++ branches/2.7.x/modules/unsupported/ogr/src/main/java/org/geotools/data/ogr/bridj/CplErrorLibrary.java 2012-01-15 18:25:20 UTC (rev 38482) @@ -0,0 +1,82 @@ +package org.geotools.data.ogr.bridj; +import java.util.Collections; +import java.util.Iterator; +import org.bridj.BridJ; +import org.bridj.CRuntime; +import org.bridj.FlagSet; +import org.bridj.IntValuedEnum; +import org.bridj.Pointer; +import org.bridj.ValuedEnum; +import org.bridj.ann.Library; +import org.bridj.ann.Runtime; +import org.geotools.data.ogr.bridj.OsrLibrary.CPLErrorHandler; +/** + * Wrapper for library <b>cplError</b><br> + * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br> + * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br> + * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> or <a href="http://bridj.googlecode.com/">BridJ</a> . + */ +@Library("cplError") +@Runtime(CRuntime.class) +public class CplErrorLibrary { + static { + BridJ.register(); + } + public enum CPLErr implements IntValuedEnum<CPLErr > { + CE_None(0), + CE_Debug(1), + CE_Warning(2), + CE_Failure(3), + CE_Fatal(4); + CPLErr(long value) { + this.value = value; + } + public final long value; + public long value() { + return this.value; + } + public Iterator<CPLErr > iterator() { + return Collections.singleton(this).iterator(); + } + public static ValuedEnum<CPLErr > fromValue(long value) { + return FlagSet.fromValue(value, values()); + } + }; + /// <i>native declaration : /home/aaime/devel/gdal/gdal-1.8.0/port/cpl_error.h</i> + public static final int CPLE_UserInterrupt = (int)9; + /// <i>native declaration : /home/aaime/devel/gdal/gdal-1.8.0/port/cpl_... [truncated message content] |