Permalink
Browse files

Merge pull request #176 from aaime/shapefile-ng

Replace existing shapefile module with shapefile-ng
  • Loading branch information...
aaime committed Apr 13, 2013
2 parents a0c728f + d67d4d2 commit 7ea446640111c69de4ecb908af23568734b2ac6e
Showing 334 changed files with 4,706 additions and 15,077 deletions.
@@ -89,28 +89,17 @@ These examples bring up a couple of questions:
We are using a FactoryFinder (rather than just saying new
ShapefileDataStore ) so GeoTools can have a look at your specific
- fiel choose the right implementation for the job.
-
- Currently GeoTools has two implementations:
-
- * ShapefileDataStore
-
- Provided by **ShapefileDataStoreFactory** for direct access to a
- shapefile, suitable for shapefiles located on network shares and web
- services
-
- * IndexedShapefileDataStore
-
- Provided by **IndexedShapefileDataStoreFactory** to makes use of
- (or create) a spatial index for fast access
+ configuration and choose the right implementation for the job.
+ Store implementation might change in time, accessing the stores via the
+ factory ensures your client code does not need to be changed when this happens.
+
* Q: What do we put it the Map?
That's a hard question which forces us to read the documentation:
* :doc: `shape` (user guide)
* `ShapefileDataStoreFactory <http://docs.geotools.org/stable/javadocs/org/geotools/data/shapefile/ShapefileDataStoreFactory.html>`_ (javadocs)
- * `IndexedShapefileDataStoreFactory <http://docs.geotools.org/stable/javadocs/org/geotools/data/shapefile/indexed/IndexedShapefileDataStoreFactory.html>`_ (javadocs)
This information is also available at runtime via the
**DataStoreFactorySpi,getParameterInfo()** method. You can use this
@@ -170,12 +159,12 @@ You can also dodge the FactoryFinder and make use of the following quick hacks.
This is not wise (as the implementation may change over time) but here is how it is done.
-* Use new ShapefileDataStore::
+* Use ShapefileDataStore::
File file = new File("example.shp");
- URI namespace = new URI("refractions");
- boolean useMemoryMapped = true;
- DataStore shapefile = new ShapefileDataStore( example.toURL(), namespace, useMemoryMapped );
+ DataStore shapefile = new ShapefileDataStore( example.toURL());
+ shapefile.setNamespace(new URI("refractions"));
+ shapefile.setMemoryMapped(true ;
String typeName = shapefile.getTypeName(); // should be "example"
FeatureType schema = shapefile.getSchema( typeName ); // should be "refractions.example"
@@ -188,26 +177,9 @@ This is not wise (as the implementation may change over time) but here is how it
application can we ask you to use the DataStoreFactoryFinder. It will
let the library sort out what implementation is appropriate.
-* Use new IndexedShapefileDataStore::
-
- File file = new File("example.shp");
- URI namespace = new URI("refractions");
- boolean memoryMapped = true;
- boolean createIndex = true;
- byte treeType = IndexedShapefileDataStore.TREE_QIX;
-
- DataStore shapefile = new IndexedShapefileDataStore( example.toURL(), namespace, memoryMapped, createIndex, treeType );
-
- String typeName = shapefile.getTypeName(); // should be "example"
- ...
-
- This hack may be fine for a quick code example, but in a real
- application can we ask you to use the DataStoreFactoryFinder. It will
- let the library sort out what implementation is appropriate.
-
-* Use IndexedShapefileDataStoreFactory::
+* Use ShapefileDataStoreFactory::
- FileDataStoreFactorySpi factory = new IndexedShapefileDataStoreFactory();
+ FileDataStoreFactorySpi factory = new ShapefileDataStoreFactory();
File file = new File("example.shp");
Map map = Collections.singletonMap( "url", file.toURL() );
@@ -34,9 +34,22 @@ The following connection parameters are available:
| "charset" | Optional: Chartset used to decode strings in the |
| | DBF file |
+-------------------------+----------------------------------------------------+
-| "timezone | Optional: Timezone used to parse dates in the |
+| "timezone" | Optional: Timezone used to parse dates in the |
| | DBF file |
+-------------------------+----------------------------------------------------+
+| "memory mapped buffer" | Optional: memory map the files (unadvisable for |
+| | large files under windows, defaults to false) |
++------------------------------------------------------------------------------+
+| "cache memory maps" | Optional: when memory mapping, cache and reuse |
+| | memory maps (defaults to true) |
++------------------------------------------------------------------------------+
+| "create spatial index" | Optional: if false, won't try to create a spatial |
+| | index if missing (defaults to true) |
++------------------------------------------------------------------------------+
+| "enable spatial index" | Optional: if false, the spatial index won't be used|
+| | even if available (and won't be created if missing |
++-------------------------+----------------------------------------------------+
+
This information is also in the `javadocs <http://docs.geotools.org/latest/javadocs/org/geotools/data/shapefile/ShapefileDataStoreFactory.html>`_ .
@@ -134,7 +147,7 @@ Supports:
Limitations:
-* only work with MultiLineStirngs, MultiPolygon or MultiPoint. GIS data often travels
+* only work with MultiLineStrings, MultiPolygon or MultiPoint. GIS data often travels
in herds - so being restricted to the plural form is not a great limitation.
* only work with fixed length strings (you will find the FeatureType
has a restriction to help you check this, and warnings will be produced if
@@ -28,7 +28,7 @@ And a couple that are no longer used:
AbstractDataStore
^^^^^^^^^^^^^^^^^
-The **AbstractDataStore** is the super class for ShapefileDataStore and the legacy JDBC DataStores.
+The **AbstractDataStore** is an old base class for DataStore implementations, currently used only by MemoryDataStore and PropertyDataStore. All new stores use **ContentDataStore** instead.
.. image:: /images/AbstractDataStore.PNG
View
@@ -129,8 +129,7 @@ Bad practice with direct dependency on ShapeFileDataStoreFactory::
ShapeFileDataStore = factory.createDataStore( file );
This code example would have been fine for GeoTools 2.1, however for GeoTools 2.2 an "indexed"
-shapefile datastore was created with far better performance. The factory would be smart enough
-to create an IndexedShapeFileDataStore if an index file was available.
+shapefile datastore was created with far better performance.
Here is a replacement that allows GeoTools to return an indexed datastore if one is available::
@@ -365,7 +364,7 @@ Sometimes you just need to go ahead and code it like you mean it. The GeoTools p
You can just use a specific factory that is known to you::
- DataStoreFactorySpi factory = new IndexedShapefileDataStoreFactory();
+ DataStoreFactorySpi factory = new ShapefileDataStoreFactory();
File file = new File("example.shp");
Map map = Collections.singletonMap( "url", file.toURL() );
@@ -394,11 +393,12 @@ You can skip the whole Factory madness and just do normal Java coding::
File file = new File("example.shp");
URI namespace = new URI("refractions");
- boolean useMemoryMapped = true;
- ShapefileDataStore shapefile = new ShapefileDataStore( example.toURL(), namespace, useMemoryMapped );
+ ShapefileDataStore shapefile = new ShapefileDataStore( example.toURL());
+ shapefile.setNamespace(namespace);
+ shapefile.setMemoryMapped(true);
You are depending on a exact class here, violating the plug-in system and so on. Chances are that GeoTools should not let you do this (by making the constructor package visible and forcing you to use the associated DataStoreFactory instead).
-This option is fine for quick hacks, you may find that the ShapefileDataStore has additional methods (to handle such things as forcing the "prj" file to be rewritten.::
+This option is fine for quick hacks, you may find that the ShapefileDataStore has additional methods (to handle such things as forcing the "prj" file to be rewritten)::
shapefile.forceSchemaCRS( CRS.decode( "EPSG:4326" ) );
@@ -61,6 +61,7 @@
import org.geotools.filter.function.Collection_SumFunction;
import org.geotools.filter.function.Collection_UniqueFunction;
import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.referencing.CRS;
import org.geotools.util.NullProgressListener;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
@@ -618,14 +619,20 @@ public final ContentFeatureCollection getFeatures(Query query)
// reprojection
if ( !canReproject() ) {
- if (query.getCoordinateSystemReproject() != null) {
- try {
- reader = new ReprojectFeatureReader(reader, query.getCoordinateSystemReproject());
- } catch (Exception e) {
- if(e instanceof IOException)
- throw (IOException) e;
- else
- throw (IOException) new IOException("Error occurred trying to reproject data").initCause(e);
+ CoordinateReferenceSystem targetCRS = query.getCoordinateSystemReproject();
+ if (targetCRS != null) {
+ CoordinateReferenceSystem nativeCRS = reader.getFeatureType().getCoordinateReferenceSystem();
+ if(nativeCRS == null) {
+ throw new IOException("Cannot reproject data, the source CRS is not available");
+ } else if(!nativeCRS.equals(targetCRS)) {
+ try {
+ reader = new ReprojectFeatureReader(reader, targetCRS);
+ } catch (Exception e) {
+ if(e instanceof IOException)
+ throw (IOException) e;
+ else
+ throw (IOException) new IOException("Error occurred trying to reproject data").initCause(e);
+ }
}
}
}
@@ -582,12 +582,12 @@ protected void testNameAndInfo(String configName) {
}
- protected void testQueryCapabilities(String configName) {
+ protected void testQueryCapabilities(String configName, boolean pureShapefile) {
try {
PreGeneralizedDataStore ds = getDataStore(configName);
SimpleFeatureSource fs = ds.getFeatureSource("GenStreams");
- assertFalse(fs.getQueryCapabilities().isOffsetSupported());
+ assertEquals(pureShapefile, fs.getQueryCapabilities().isOffsetSupported());
assertTrue(fs.getQueryCapabilities().isReliableFIDSupported());
PropertyName propertyName = new PropertyName() {
@@ -614,7 +614,7 @@ public NamespaceSupport getNamespaceContext() {
};
SortOrder so = SortOrder.valueOf("CAT_ID");
- assertFalse(fs.getQueryCapabilities().supportsSorting(
+ assertEquals(pureShapefile, fs.getQueryCapabilities().supportsSorting(
new SortBy[] { new SortByImpl(propertyName, so) }));
ds.dispose();
@@ -64,7 +64,7 @@ public void testGetNameAndInfo() {
}
public void testQueryCapabilities() {
- testQueryCapabilities(ConfigName);
+ testQueryCapabilities(ConfigName, false);
}
public void testGetSchema() {
@@ -63,7 +63,7 @@ public void testGetNameAndInfo() {
}
public void testQueryCapabilities() {
- testQueryCapabilities(ConfigName);
+ testQueryCapabilities(ConfigName, false);
}
public void testGetSchema() {
@@ -70,7 +70,7 @@ public void testGetNameAndInfo() {
}
public void testQueryCapabilities() {
- testQueryCapabilities(ConfigName);
+ testQueryCapabilities(ConfigName, true);
}
public void testGetSchema() {
@@ -64,7 +64,7 @@ public void testGetNameAndInfo() {
}
public void testQueryCapabilities() {
- testQueryCapabilities(ConfigName);
+ testQueryCapabilities(ConfigName, false);
}
public void testGetSchema() {
@@ -273,14 +273,15 @@ static void writeFootprintSummary(
if (footprintsLocationGeometryMap.isEmpty())
return;
- final String[] typeNames = store.getTypeNames();
- if (typeNames.length <= 0) {
- throw new IllegalArgumentException("Problems when opening the shapefile, no typenames for the schema are defined");
- }
- final String typeName = typeNames[0];
FileWriter footprintWriter = null;
FeatureIterator<SimpleFeature> it=null;
try {
+ final String[] typeNames = store.getTypeNames();
+ if (typeNames.length <= 0) {
+ throw new IllegalArgumentException("Problems when opening the shapefile, no typenames for the schema are defined");
+ }
+ final String typeName = typeNames[0];
+
final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = store.getFeatureSource(typeName);
final FeatureCollection<SimpleFeatureType, SimpleFeature> features = featureSource.getFeatures();
@@ -362,7 +362,7 @@ private static boolean checkForUrl( Object source, Hints hints){
}
ShapefileDataStore store = new ShapefileDataStore(sourceURL);
- store.setDbftimeZone(Utils.UTC_TIME_ZONE);
+ store.setTimeZone(Utils.UTC_TIME_ZONE);
tileIndexStore = store;
}
@@ -499,9 +499,9 @@ protected void handleFile(final File fileBeingProcessed, final int depth, final
final SimpleFeatureTypeBuilder featureBuilder = new SimpleFeatureTypeBuilder();
featureBuilder.setName(runConfiguration.getIndexName());
featureBuilder.setNamespaceURI("http://www.geo-solutions.it/");
- featureBuilder.add(runConfiguration.getLocationAttribute().trim(), String.class);
featureBuilder.add("the_geom", Polygon.class,actualCRS);
featureBuilder.setDefaultGeometry("the_geom");
+ featureBuilder.add(runConfiguration.getLocationAttribute().trim(), String.class);
String timeAttribute = runConfiguration.getTimeAttribute();
addAttributes(timeAttribute, featureBuilder, Date.class);
indexSchema = featureBuilder.buildFeatureType();
@@ -37,7 +37,7 @@
</scm>
<description>
- DataStore supporting the ESRI shapefile format.
+ DataStore supporting the ESRI shapefile format. NG version
</description>
<licenses>
@@ -143,26 +143,19 @@
<artifactId>gt-data</artifactId>
<version>${project.version}</version>
</dependency>
+
<dependency>
- <groupId>org.geotools</groupId>
- <artifactId>gt-sample-data</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
+ <groupId>jdom</groupId>
+ <artifactId>jdom</artifactId>
</dependency>
- <!-- because main and sample-data depend on referencing we need a tie breaker -->
+
<dependency>
<groupId>org.geotools</groupId>
- <artifactId>gt-referencing</artifactId>
+ <artifactId>gt-sample-data</artifactId>
<version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>jdom</groupId>
- <artifactId>jdom</artifactId>
- <!-- The version number is specified in the parent POM. -->
+ <scope>test</scope>
</dependency>
- <!-- We need this to make the referencing module useful -->
<dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-epsg-hsql</artifactId>
@@ -171,17 +164,4 @@
</dependency>
</dependencies>
-
- <!-- =========================================================== -->
- <!-- Build Configuration -->
- <!-- =========================================================== -->
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-surefire-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
</project>
@@ -14,12 +14,12 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
-package org.geotools.data.shapefile.ng;
+package org.geotools.data.shapefile;
import java.io.IOException;
import java.util.Iterator;
-import org.geotools.data.shapefile.ng.index.CloseableIterator;
+import org.geotools.data.shapefile.index.CloseableIterator;
/**
* Wraps a plain iterator into a closeable one.
@@ -14,7 +14,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
-package org.geotools.data.shapefile.ng;
+package org.geotools.data.shapefile;
import java.util.Comparator;
Oops, something went wrong.

0 comments on commit 7ea4466

Please sign in to comment.