You can subscribe to this list here.
| 2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(39) |
Dec
(70) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2002 |
Jan
(52) |
Feb
(168) |
Mar
(248) |
Apr
(143) |
May
(418) |
Jun
(558) |
Jul
(702) |
Aug
(311) |
Sep
(141) |
Oct
(350) |
Nov
(172) |
Dec
(182) |
| 2003 |
Jan
(320) |
Feb
(362) |
Mar
(356) |
Apr
(218) |
May
(447) |
Jun
(203) |
Jul
(745) |
Aug
(494) |
Sep
(175) |
Oct
(422) |
Nov
(554) |
Dec
(162) |
| 2004 |
Jan
(217) |
Feb
(353) |
Mar
(228) |
Apr
(407) |
May
(211) |
Jun
(270) |
Jul
(264) |
Aug
(198) |
Sep
(268) |
Oct
(227) |
Nov
(118) |
Dec
(47) |
| 2005 |
Jan
(207) |
Feb
(243) |
Mar
(297) |
Apr
(197) |
May
(281) |
Jun
(166) |
Jul
(164) |
Aug
(92) |
Sep
(155) |
Oct
(196) |
Nov
(189) |
Dec
(114) |
| 2006 |
Jan
(129) |
Feb
(219) |
Mar
(274) |
Apr
(213) |
May
(245) |
Jun
(220) |
Jul
(376) |
Aug
(347) |
Sep
(179) |
Oct
(493) |
Nov
(448) |
Dec
(339) |
| 2007 |
Jan
(304) |
Feb
(273) |
Mar
(237) |
Apr
(186) |
May
(215) |
Jun
(320) |
Jul
(229) |
Aug
(313) |
Sep
(331) |
Oct
(279) |
Nov
(347) |
Dec
(266) |
| 2008 |
Jan
(332) |
Feb
(280) |
Mar
(203) |
Apr
(277) |
May
(301) |
Jun
(356) |
Jul
(292) |
Aug
(203) |
Sep
(277) |
Oct
(142) |
Nov
(210) |
Dec
(239) |
| 2009 |
Jan
(250) |
Feb
(193) |
Mar
(174) |
Apr
(183) |
May
(342) |
Jun
(230) |
Jul
(292) |
Aug
(161) |
Sep
(204) |
Oct
(280) |
Nov
(281) |
Dec
(175) |
| 2010 |
Jan
(113) |
Feb
(106) |
Mar
(199) |
Apr
(166) |
May
(298) |
Jun
(147) |
Jul
(175) |
Aug
(192) |
Sep
(71) |
Oct
(79) |
Nov
(58) |
Dec
(55) |
| 2011 |
Jan
(83) |
Feb
(169) |
Mar
(142) |
Apr
(207) |
May
(311) |
Jun
(183) |
Jul
(218) |
Aug
(190) |
Sep
(158) |
Oct
(197) |
Nov
(93) |
Dec
(74) |
| 2012 |
Jan
(92) |
Feb
(50) |
Mar
(64) |
Apr
(45) |
May
(100) |
Jun
(70) |
Jul
(3) |
Aug
(1) |
Sep
(2) |
Oct
(5) |
Nov
(7) |
Dec
(4) |
| 2013 |
Jan
(6) |
Feb
(2) |
Mar
(2) |
Apr
(4) |
May
(3) |
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2014 |
Jan
(2) |
Feb
(2) |
Mar
(2) |
Apr
(3) |
May
(3) |
Jun
(1) |
Jul
|
Aug
(4) |
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2015 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(1) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
(1) |
| 2016 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
(1) |
Jul
|
Aug
(3) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2017 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <svn...@os...> - 2012-03-27 09:50:52
|
Author: aaime
Date: 2012-03-27 02:50:39 -0700 (Tue, 27 Mar 2012)
New Revision: 38648
Added:
branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_0_0/ConnectionFactoryWrapper.java
branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_1_0/HttpProtocolWrapper.java
Modified:
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/WFSDataStore.java
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/MapServerWFSStrategy.java
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/NonStrictWFSStrategy.java
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/StrictWFSStrategy.java
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/WFS100ProtocolHandler.java
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/WFS_1_0_0_DataStore.java
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/GetFeatureQueryAdapter.java
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/WFS_1_1_0_DataStore.java
branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/WFS_1_1_0_Protocol.java
branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_0_0/GeoServerOnlineTest.java
branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_1_0/GeoServerOnlineTest.java
Log:
[GEOT-4092] Add support for vendor parameters in WFS data store
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/WFSDataStore.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/WFSDataStore.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/WFSDataStore.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -18,12 +18,14 @@
import java.net.URI;
import java.net.URL;
+import java.util.Map;
import java.util.Set;
import javax.xml.namespace.QName;
import org.geotools.data.DataAccess;
import org.geotools.data.DataStore;
+import org.geotools.factory.Hints.ClassKey;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -39,7 +41,16 @@
* /data/wfs/WFSDataStore.java $
*/
public interface WFSDataStore extends DataStore {
+
/**
+ * Provides the vendor parameters to be used in a query
+ *
+ * @since 2.7.5
+ */
+ public static final ClassKey WFS_VENDOR_PARAMETERS = new ClassKey(Map.class);
+
+
+ /**
* Overrides {@link DataAccess#getInfo()} so it type narrows to a {@link WFSServiceInfo}
*
* @return service information
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/MapServerWFSStrategy.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/MapServerWFSStrategy.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/MapServerWFSStrategy.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -94,8 +94,8 @@
BBOX newFilter = fac.bbox(attName, bbox.getMinX(), bbox.getMinY(),
bbox.getMaxX(), bbox.getMaxY(), "EPSG:4326");
- query2=new DefaultQuery(query.getTypeName(), query.getNamespace(), newFilter,
- query.getMaxFeatures(), query.getPropertyNames(), query.getHandle());
+ query2 = new DefaultQuery(query);
+ query2.setFilter(newFilter);
}
} catch (IllegalFilterException e) {
query2=query;
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/NonStrictWFSStrategy.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/NonStrictWFSStrategy.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/NonStrictWFSStrategy.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -27,6 +27,7 @@
import org.geotools.data.crs.ForceCoordinateSystemFeatureReader;
import org.geotools.data.ows.FeatureSetDescription;
import org.geotools.data.ows.WFSCapabilities;
+import org.geotools.data.wfs.protocol.http.HttpMethod;
import org.geotools.feature.SchemaException;
import org.geotools.filter.Filters;
import org.geotools.filter.visitor.WFSBBoxFilterVisitor;
@@ -95,10 +96,18 @@
protected FeatureReader<SimpleFeatureType, SimpleFeature> createFeatureReader(Transaction transaction, Query query)
throws IOException {
Data data;
- data = createFeatureReaderPOST(query, transaction);
-
- if (data.reader == null)
+
+ if(store.preferredProtocol == HttpMethod.POST) {
+ data = createFeatureReaderPOST(query, transaction);
+
+ if (data.reader == null)
+ data = createFeatureReaderGET(query, transaction);
+ } else {
data = createFeatureReaderGET(query, transaction);
+
+ if (data.reader == null)
+ data = createFeatureReaderPOST(query, transaction);
+ }
if (data.reader == null && data.saxException != null)
throw (IOException) new IOException(data.saxException.toString()).initCause(data.saxException);
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/StrictWFSStrategy.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/StrictWFSStrategy.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/StrictWFSStrategy.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -153,12 +153,13 @@
if( visitor.requiresPostProcessing() && query.getPropertyNames()!=Query.ALL_NAMES){
FilterAttributeExtractor attributeExtractor=new FilterAttributeExtractor();
query.getFilter().accept( attributeExtractor, null );
- Set properties=new HashSet(attributeExtractor.getAttributeNameSet());
+ Set properties = new HashSet(attributeExtractor.getAttributeNameSet());
properties.addAll(Arrays.asList(query.getPropertyNames()));
- this.query=new DefaultQuery(query.getTypeName(), query.getFilter(), query.getMaxFeatures(),
- (String[]) properties.toArray(new String[0]), query.getHandle());
- }else
+ this.query=new DefaultQuery(query);
+ this.query.setPropertyNames((String[]) properties.toArray(new String[0]));
+ } else {
this.query=query;
+ }
this.filter=visitor.getFilter();
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/WFS100ProtocolHandler.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/WFS100ProtocolHandler.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/WFS100ProtocolHandler.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -56,7 +56,7 @@
}
@SuppressWarnings("unchecked")
- private WFSCapabilities parseCapabilities(InputStream capabilitiesReader) throws IOException {
+ protected WFSCapabilities parseCapabilities(InputStream capabilitiesReader) throws IOException {
// TODO: move to some 1.0.0 specific class
Map hints = new HashMap();
hints.put(DocumentFactory.VALIDATION_HINT, Boolean.FALSE);
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/WFS_1_0_0_DataStore.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/WFS_1_0_0_DataStore.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_0_0/WFS_1_0_0_DataStore.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -515,6 +515,15 @@
}
}
}
+
+ // inject vendor params, if any
+ if(request.getHints() != null && request.getHints().get(WFSDataStore.WFS_VENDOR_PARAMETERS) != null) {
+ Map<String, String> vendorParams = (Map<String, String>) request.getHints().get(WFSDataStore.WFS_VENDOR_PARAMETERS);
+ for (Map.Entry<String, String> entry : vendorParams.entrySet()) {
+ url += "&" + entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), protocolHandler
+ .getEncoding());
+ }
+ }
}
}
@@ -669,6 +678,30 @@
return null;
}
+ // inject vendor params, if any
+ if(query != null && query.getHints() != null && query.getHints().get(WFSDataStore.WFS_VENDOR_PARAMETERS) != null) {
+ String url = postUrl.toString();
+ if ((url == null) || !url.endsWith("?")) {
+ url += "?";
+ }
+
+ boolean first = true;
+ if(query.getHints() != null && query.getHints().get(WFSDataStore.WFS_VENDOR_PARAMETERS) != null) {
+ Map<String, String> vendorParams = (Map<String, String>) query.getHints().get(WFSDataStore.WFS_VENDOR_PARAMETERS);
+ for (Map.Entry<String, String> entry : vendorParams.entrySet()) {
+ if(first) {
+ first = false;
+ } else {
+ url += "&";
+ }
+ url += entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), protocolHandler
+ .getEncoding());
+ }
+ }
+
+ postUrl = new URL(url);
+ }
+
HttpURLConnection hc = protocolHandler.getConnectionFactory().getConnection(postUrl, POST);
Writer w = getOutputStream(hc);
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/GetFeatureQueryAdapter.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/GetFeatureQueryAdapter.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/GetFeatureQueryAdapter.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -16,7 +16,10 @@
*/
package org.geotools.data.wfs.v1_1_0;
+import java.util.Map;
+
import org.geotools.data.Query;
+import org.geotools.data.wfs.WFSDataStore;
import org.geotools.data.wfs.protocol.wfs.GetFeature;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;
@@ -71,5 +74,13 @@
public SortBy[] getSortBy() {
return query.getSortBy();
}
+
+ public Map<String, String> getVendorParameter() {
+ if(query.getHints() != null) {
+ return (Map<String, String>) query.getHints().get(WFSDataStore.WFS_VENDOR_PARAMETERS);
+ } else {
+ return null;
+ }
+ }
}
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/WFS_1_1_0_DataStore.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/WFS_1_1_0_DataStore.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/WFS_1_1_0_DataStore.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -109,7 +109,7 @@
*/
private static final boolean DEFAULT_HTTP_METHOD = true;
- private final WFSProtocol wfs;
+ protected WFSProtocol wfs;
private Map<String, SimpleFeatureType> byTypeNameTypes;
@@ -319,8 +319,8 @@
Filter[] filters = wfs.splitFilters(query.getFilter());
Filter supportedFilter = filters[0];
Filter postFilter = filters[1];
- System.out.println("Supported filter: " + supportedFilter);
- System.out.println("Unupported filter: " + postFilter);
+ LOGGER.fine("Supported filter: " + supportedFilter);
+ LOGGER.fine("Unupported filter: " + postFilter);
((DefaultQuery) query).setFilter(supportedFilter);
((DefaultQuery) query).setMaxFeatures(getMaxFeatures(query));
Modified: branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/WFS_1_1_0_Protocol.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/WFS_1_1_0_Protocol.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/main/java/org/geotools/data/wfs/v1_1_0/WFS_1_1_0_Protocol.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -29,6 +29,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
+import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
@@ -70,6 +71,7 @@
import org.apache.commons.io.IOUtils;
import org.eclipse.emf.ecore.EObject;
import org.geotools.data.DataSourceException;
+import org.geotools.data.wfs.WFSDataStore;
import org.geotools.data.wfs.protocol.http.HTTPProtocol;
import org.geotools.data.wfs.protocol.http.HTTPResponse;
import org.geotools.data.wfs.protocol.http.HttpMethod;
@@ -135,9 +137,9 @@
*/
private final Map<String, FeatureTypeType> typeInfos;
- private HTTPProtocol http;
+ protected HTTPProtocol http;
- private final Charset defaultEncoding;
+ protected final Charset defaultEncoding;
public WFS_1_1_0_Protocol(InputStream capabilitiesReader, HTTPProtocol http,
Charset defaultEncoding) throws IOException {
@@ -468,11 +470,18 @@
URL url = getOperationURL(WFSOperationType.GET_FEATURE, false);
RequestComponents reqParts = strategy.createGetFeatureRequest(this, request);
+ GetFeatureType requestType = reqParts.getServerRequest();
+
+ // build the kvp taking into account eventual vendor params
Map<String, String> getFeatureKvp = reqParts.getKvpParameters();
- GetFeatureType requestType = reqParts.getServerRequest();
+ if(request instanceof GetFeatureQueryAdapter) {
+ GetFeatureQueryAdapter adapter = (GetFeatureQueryAdapter) request;
+ if(adapter.getVendorParameter() != null) {
+ getFeatureKvp.putAll(adapter.getVendorParameter());
+ }
+ }
+
- System.out.println(" > getFeatureGET: Request url: " + url + ". Parameters: "
- + getFeatureKvp);
WFSResponse response = issueGetRequest(requestType, url, getFeatureKvp);
return response;
@@ -486,7 +495,30 @@
throw new UnsupportedOperationException(
"The server does not support GetFeature for HTTP method POST");
}
- URL url = getOperationURL(WFSOperationType.GET_FEATURE, true);
+ URL postURL = getOperationURL(WFSOperationType.GET_FEATURE, true);
+
+ // support vendor parameters, GeoServer way
+ if(request instanceof GetFeatureQueryAdapter) {
+ GetFeatureQueryAdapter adapter = (GetFeatureQueryAdapter) request;
+ if(adapter.getVendorParameter() != null) {
+ String url = postURL.toString();
+ if ((url == null) || !url.endsWith("?")) {
+ url += "?";
+ }
+
+ boolean first = true;
+ for (Map.Entry<String, String> entry : adapter.getVendorParameter().entrySet()) {
+ if(first) {
+ first = false;
+ } else {
+ url += "&";
+ }
+ url += entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), "UTF-8");
+ }
+
+ postURL = new URL(url);
+ }
+ }
RequestComponents reqParts = strategy.createGetFeatureRequest(this, request);
GetFeatureType serverRequest = reqParts.getServerRequest();
@@ -502,7 +534,7 @@
if (!XMLConstants.DEFAULT_NS_PREFIX.equals(prefix)) {
encoder.getNamespaces().declarePrefix(prefix, namespace);
}
- WFSResponse response = issuePostRequest(serverRequest, url, encoder);
+ WFSResponse response = issuePostRequest(serverRequest, postURL, encoder);
return response;
}
@@ -536,7 +568,7 @@
return typeInfos.get(typeName);
}
- private WFSCapabilitiesType parseCapabilities(InputStream capabilitiesReader)
+ protected WFSCapabilitiesType parseCapabilities(InputStream capabilitiesReader)
throws IOException {
final Configuration wfsConfig = strategy.getWfsConfiguration();
final Parser parser = new Parser(wfsConfig);
Added: branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_0_0/ConnectionFactoryWrapper.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_0_0/ConnectionFactoryWrapper.java (rev 0)
+++ branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_0_0/ConnectionFactoryWrapper.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -0,0 +1,54 @@
+package org.geotools.data.wfs.v1_0_0;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.Charset;
+
+import org.geotools.data.wfs.protocol.http.HttpMethod;
+import org.geotools.wfs.protocol.ConnectionFactory;
+
+/**
+ * Helper class for the tests
+ * @author aaime
+ *
+ */
+public class ConnectionFactoryWrapper implements ConnectionFactory {
+
+ public ConnectionFactory delegate;
+
+ public ConnectionFactoryWrapper(ConnectionFactory delegate) {
+ this.delegate = delegate;
+ }
+
+ public String getAuthUsername() {
+ return delegate.getAuthUsername();
+ }
+
+ public String getAuthPassword() {
+ return delegate.getAuthPassword();
+ }
+
+ public boolean isTryGzip() {
+ return delegate.isTryGzip();
+ }
+
+ public Charset getEncoding() {
+ return delegate.getEncoding();
+ }
+
+ public HttpURLConnection getConnection(URL query, HttpMethod method) throws IOException {
+ return delegate.getConnection(query, method);
+ }
+
+ public InputStream getInputStream(HttpURLConnection hc) throws IOException {
+ return delegate.getInputStream(hc);
+ }
+
+ public InputStream getInputStream(URL query, HttpMethod method) throws IOException {
+ return delegate.getInputStream(query, method);
+ }
+
+
+}
Modified: branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_0_0/GeoServerOnlineTest.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_0_0/GeoServerOnlineTest.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_0_0/GeoServerOnlineTest.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -17,13 +17,12 @@
*/
package org.geotools.data.wfs.v1_0_0;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.*;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
+import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.NoRouteToHostException;
import java.net.URL;
@@ -45,17 +44,22 @@
import org.geotools.data.FeatureReader;
import org.geotools.data.Query;
import org.geotools.data.Transaction;
+import org.geotools.data.ows.WFSCapabilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.data.simple.SimpleFeatureStore;
+import org.geotools.data.wfs.WFSDataStore;
import org.geotools.data.wfs.WFSDataStoreFactory;
+import org.geotools.data.wfs.protocol.http.HttpMethod;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
import org.geotools.feature.IllegalAttributeException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.filter.IllegalFilterException;
import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.wfs.protocol.ConnectionFactory;
import org.junit.Before;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
@@ -478,7 +482,75 @@
}
}
}
+
+ @Test
+ public void testVendorParametersGet() throws Exception {
+ testVendorParameters(Boolean.FALSE);
+ }
+
+ @Test
+ public void testVendorParametersPost() throws Exception {
+ testVendorParameters(Boolean.TRUE);
+ }
+ private void testVendorParameters(Boolean usePost) throws IOException {
+ if (url == null)
+ return;
+
+ Map m = new HashMap();
+ m.put(WFSDataStoreFactory.URL.key, url);
+ m.put(WFSDataStoreFactory.TIMEOUT.key, new Integer(100000));
+ m.put(WFSDataStoreFactory.PROTOCOL.key, usePost);
+ WFS_1_0_0_DataStore wfs = (WFS_1_0_0_DataStore) (new WFSDataStoreFactory())
+ .createDataStore(m);
+
+ final WFS100ProtocolHandler originalHandler = wfs.protocolHandler;
+ wfs.protocolHandler = new WFS100ProtocolHandler(null, originalHandler.getConnectionFactory()) {
+ @Override
+ protected WFSCapabilities parseCapabilities(InputStream capabilitiesReader)
+ throws IOException {
+ return originalHandler.getCapabilities();
+ }
+
+ @Override
+ public ConnectionFactory getConnectionFactory() {
+ return new ConnectionFactoryWrapper(super.getConnectionFactory()) {
+
+ @Override
+ public HttpURLConnection getConnection(URL query, HttpMethod method)
+ throws IOException {
+ String[] keyValueArray = query.getQuery().split("&");
+ Map<String, String> kvp = new HashMap<String, String>();
+ for (String keyValue : keyValueArray) {
+ String[] skv = keyValue.split("=");
+ kvp.put(skv[0], skv[1]);
+ }
+
+ // check the vendor params actually made it into the url
+ assertEquals("true", kvp.get("strict"));
+ assertEquals("mysecret", kvp.get("authkey"));
+ assertEquals("low%3A2000000%3Bhigh%3A5000000", kvp.get("viewparams"));
+
+ return super.getConnection(query, method);
+ }
+ };
+ }
+ };
+
+ Map<String, String> vparams = new HashMap<String, String>();
+ vparams.put("authkey", "mysecret");
+ vparams.put("viewparams", "low:2000000;high:5000000");
+ vparams.put("strict", "true");
+ Hints hints = new Hints(WFSDataStore.WFS_VENDOR_PARAMETERS, vparams);
+ Query q = new Query("topp:states");
+ q.setHints(hints);
+
+ // try with
+ FeatureReader fr = wfs.getFeatureReader(q, Transaction.AUTO_COMMIT);
+ assertTrue(fr.hasNext());
+ fr.close();
+ }
+
private Id createFidFilter(SimpleFeatureSource fs)
throws IOException {
SimpleFeatureIterator iter = fs.getFeatures().features();
@@ -496,4 +568,6 @@
iter.close();
}
}
+
+
}
Modified: branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_1_0/GeoServerOnlineTest.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_1_0/GeoServerOnlineTest.java 2012-03-26 08:51:38 UTC (rev 38647)
+++ branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_1_0/GeoServerOnlineTest.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -18,18 +18,42 @@
package org.geotools.data.wfs.v1_1_0;
import static org.geotools.data.wfs.v1_1_0.DataTestSupport.GEOS_STATES;
+import static org.junit.Assert.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.HttpURLConnection;
+import java.net.URL;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import net.opengis.wfs.WFSCapabilitiesType;
+
import org.geotools.data.DefaultQuery;
+import org.geotools.data.FeatureReader;
+import org.geotools.data.Query;
+import org.geotools.data.Transaction;
+import org.geotools.data.ows.WFSCapabilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
+import org.geotools.data.wfs.WFSDataStore;
+import org.geotools.data.wfs.WFSDataStoreFactory;
+import org.geotools.data.wfs.protocol.http.HTTPProtocol;
+import org.geotools.data.wfs.protocol.http.HTTPResponse;
+import org.geotools.data.wfs.protocol.http.HttpMethod;
+import org.geotools.data.wfs.protocol.wfs.WFSProtocol;
+import org.geotools.data.wfs.v1_0_0.ConnectionFactoryWrapper;
+import org.geotools.data.wfs.v1_0_0.WFS100ProtocolHandler;
+import org.geotools.data.wfs.v1_0_0.WFS_1_0_0_DataStore;
import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.factory.Hints;
+import org.geotools.wfs.protocol.ConnectionFactory;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
@@ -44,7 +68,7 @@
public class GeoServerOnlineTest extends AbstractWfsDataStoreOnlineTest {
- public static final String SERVER_URL = "http://sigma.openplans.org:8080/geoserver/wfs?service=WFS&request=GetCapabilities&version=1.1.0"; //$NON-NLS-1$
+ public static final String SERVER_URL = "http://localhost:8080/geoserver/wfs?service=WFS&request=GetCapabilities&version=1.1.0"; //$NON-NLS-1$
public GeoServerOnlineTest() {
super(SERVER_URL, GEOS_STATES, "the_geom", MultiPolygon.class, 49, ff.id(Collections
@@ -93,5 +117,76 @@
iterator.close();
}
}
+
+ @Test
+ public void testVendorParametersGet() throws Exception {
+ testVendorParameters(Boolean.FALSE);
+ }
+
+ @Test
+ public void testVendorParametersPost() throws Exception {
+ testVendorParameters(Boolean.TRUE);
+ }
+ private void testVendorParameters(Boolean usePost) throws IOException {
+ if (Boolean.FALSE.equals(serviceAvailable)) {
+ return;
+ }
+
+ // we alter the data store, thus we cannot use the static "wfs" field, we need to create a new one
+ Map<String, Serializable> params = new HashMap<String, Serializable>();
+ params.put(WFSDataStoreFactory.URL.key, SERVER_URL);
+ params.put(WFSDataStoreFactory.PROTOCOL.key, usePost);
+ params.put("USE_PULL_PARSER", Boolean.TRUE);
+ WFSDataStoreFactory dataStoreFactory = new WFSDataStoreFactory();
+ WFSDataStore wfs = dataStoreFactory.createDataStore(params);
+
+ final WFS_1_1_0_Protocol originalHandler = (WFS_1_1_0_Protocol) ((WFS_1_1_0_DataStore) wfs).wfs;
+ originalHandler.http = new HttpProtocolWrapper(originalHandler.http) {
+
+ @Override
+ public HTTPResponse issueGet(URL baseUrl, Map<String, String> kvp) throws IOException {
+ // check the vendor params actually made it into the url (at this stage they are not url encoded)
+ assertEquals("true", kvp.get("strict"));
+ assertEquals("mysecret", kvp.get("authkey"));
+ assertEquals("low:2000000;high:5000000", kvp.get("viewparams"));
+
+ return super.issueGet(baseUrl, kvp);
+ }
+
+ @Override
+ public HTTPResponse issuePost(URL targetUrl, POSTCallBack callback) throws IOException {
+ String[] keyValueArray = targetUrl.getQuery().split("&");
+ Map<String, String> kvp = new HashMap<String, String>();
+ for (String keyValue : keyValueArray) {
+ String[] skv = keyValue.split("=");
+ kvp.put(skv[0], skv[1]);
+ }
+
+ // check the vendor params actually made it into the url
+ assertEquals("true", kvp.get("strict"));
+ assertEquals("mysecret", kvp.get("authkey"));
+ assertEquals("low%3A2000000%3Bhigh%3A5000000", kvp.get("viewparams"));
+
+ return super.issuePost(targetUrl, callback);
+ }
+
+ };
+
+
+ Map<String, String> vparams = new HashMap<String, String>();
+ vparams.put("authkey", "mysecret");
+ vparams.put("viewparams", "low:2000000;high:5000000");
+ vparams.put("strict", "true");
+ Hints hints = new Hints(WFSDataStore.WFS_VENDOR_PARAMETERS, vparams);
+ Query q = new Query("topp:states");
+ q.setHints(hints);
+
+ // read some features, check
+ FeatureReader fr = wfs.getFeatureReader(q, Transaction.AUTO_COMMIT);
+ assertTrue(fr.hasNext());
+ fr.close();
+ }
+
+
}
Added: branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_1_0/HttpProtocolWrapper.java
===================================================================
--- branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_1_0/HttpProtocolWrapper.java (rev 0)
+++ branches/2.7.x/modules/unsupported/wfs/src/test/java/org/geotools/data/wfs/v1_1_0/HttpProtocolWrapper.java 2012-03-27 09:50:39 UTC (rev 38648)
@@ -0,0 +1,56 @@
+package org.geotools.data.wfs.v1_1_0;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Map;
+
+import org.geotools.data.wfs.protocol.http.HTTPProtocol;
+import org.geotools.data.wfs.protocol.http.HTTPResponse;
+
+public class HttpProtocolWrapper implements HTTPProtocol {
+
+ HTTPProtocol delegate;
+
+ public HttpProtocolWrapper(HTTPProtocol delegate) {
+ this.delegate = delegate;
+ }
+
+ public void setTryGzip(boolean tryGzip) {
+ delegate.setTryGzip(tryGzip);
+ }
+
+ public boolean isTryGzip() {
+ return delegate.isTryGzip();
+ }
+
+ public void setAuth(String username, String password) {
+ delegate.setAuth(username, password);
+ }
+
+ public boolean isAuthenticating() {
+ return delegate.isAuthenticating();
+ }
+
+ public void setTimeoutMillis(int milliseconds) {
+ delegate.setTimeoutMillis(milliseconds);
+ }
+
+ public int getTimeoutMillis() {
+ return delegate.getTimeoutMillis();
+ }
+
+ public HTTPResponse issueGet(URL baseUrl, Map<String, String> kvp) throws IOException {
+ return delegate.issueGet(baseUrl, kvp);
+ }
+
+ public HTTPResponse issuePost(URL targetUrl, POSTCallBack callback) throws IOException {
+ return delegate.issuePost(targetUrl, callback);
+ }
+
+ public URL createUrl(URL baseUrl, Map<String, String> queryStringKvp)
+ throws MalformedURLException {
+ return delegate.createUrl(baseUrl, queryStringKvp);
+ }
+
+}
|
|
From: <svn...@os...> - 2012-03-26 08:51:45
|
Author: ang05a
Date: 2012-03-26 01:51:38 -0700 (Mon, 26 Mar 2012)
New Revision: 38647
Modified:
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java
Log:
Fix app-schema bug for isList with simple types.
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-03-26 04:15:48 UTC (rev 38646)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/DataAccessMappingFeatureIterator.java 2012-03-26 08:51:38 UTC (rev 38647)
@@ -41,6 +41,7 @@
import org.geotools.data.joining.JoiningNestedAttributeMapping;
import org.geotools.data.joining.JoiningQuery;
import org.geotools.feature.AttributeBuilder;
+import org.geotools.feature.ComplexAttributeImpl;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureImpl;
import org.geotools.feature.FeatureIterator;
@@ -830,13 +831,13 @@
String valueString = StringUtils.join(values, " ");
StepList fullPath = attMapping.getTargetXPath();
StepList leafPath = fullPath.subList(fullPath.size() - 1, fullPath.size());
- if (ComplexFeatureConstants.SIMPLE_CONTENT.equals(instance.getDescriptor()
- .getName())) {
- instance.setValue(valueString);
- } else {
+ if (instance instanceof ComplexAttributeImpl) {
// xpath builder will work out the leaf attribute to set values on
xpathAttributeBuilder.set(instance, leafPath, valueString, null, null,
false, sourceExpr);
+ } else {
+ // simple attributes
+ instance.setValue(valueString);
}
}
} else if (attMapping.isMultiValued()) {
|
|
From: <svn...@os...> - 2012-03-26 04:15:55
|
Author: bencaradocdavies
Date: 2012-03-25 21:15:48 -0700 (Sun, 25 Mar 2012)
New Revision: 38646
Modified:
trunk/modules/extension/app-schema/app-schema/pom.xml
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/EmfAppSchemaReader.java
Log:
GEOT-4088: Use xpp3_min in app-schema
Modified: trunk/modules/extension/app-schema/app-schema/pom.xml
===================================================================
--- trunk/modules/extension/app-schema/app-schema/pom.xml 2012-03-25 09:54:07 UTC (rev 38645)
+++ trunk/modules/extension/app-schema/app-schema/pom.xml 2012-03-26 04:15:48 UTC (rev 38646)
@@ -112,7 +112,7 @@
</dependency>
<dependency>
<groupId>xpp3</groupId>
- <artifactId>xpp3</artifactId>
+ <artifactId>xpp3_min</artifactId>
</dependency>
<dependency>
<!-- for FilenameUtils -->
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/EmfAppSchemaReader.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/EmfAppSchemaReader.java 2012-03-25 09:54:07 UTC (rev 38645)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/EmfAppSchemaReader.java 2012-03-26 04:15:48 UTC (rev 38646)
@@ -38,9 +38,9 @@
import org.geotools.xml.Schemas;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType;
+import org.xmlpull.mxp1.MXParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
/**
* Parses an application schema given by a gtxml {@link Configuration} into a set of
@@ -167,12 +167,9 @@
XmlPullParser parser = null;
try {
- XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
- factory.setNamespaceAware(true);
- factory.setValidating(false);
-
// parse root element
- parser = factory.newPullParser();
+ parser = new MXParser();
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(input, "UTF-8");
parser.nextTag();
|
|
From: <svn...@os...> - 2012-03-25 09:54:13
|
Author: aaime
Date: 2012-03-25 02:54:07 -0700 (Sun, 25 Mar 2012)
New Revision: 38645
Modified:
branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStoreFactory.java
Log:
[GEOT-4087] Make connection validation on by default
Modified: branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStoreFactory.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStoreFactory.java 2012-03-25 09:52:36 UTC (rev 38644)
+++ branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStoreFactory.java 2012-03-25 09:54:07 UTC (rev 38645)
@@ -90,7 +90,7 @@
/** If connections should be validated before using them */
public static final Param VALIDATECONN = new Param("validate connections", Boolean .class,
- "check connection is alive before using it", false, Boolean.FALSE);
+ "check connection is alive before using it", false, Boolean.TRUE);
/** If connections should be validated before using them */
public static final Param FETCHSIZE = new Param("fetch size", Integer.class,
|
|
From: <svn...@os...> - 2012-03-25 09:52:43
|
Author: aaime
Date: 2012-03-25 02:52:36 -0700 (Sun, 25 Mar 2012)
New Revision: 38644
Modified:
trunk/docs/user/library/jdbc/datastore.rst
trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStoreFactory.java
Log:
[GEOT-4087] Make connection validation on by default
Modified: trunk/docs/user/library/jdbc/datastore.rst
===================================================================
--- trunk/docs/user/library/jdbc/datastore.rst 2012-03-25 09:40:50 UTC (rev 38643)
+++ trunk/docs/user/library/jdbc/datastore.rst 2012-03-25 09:52:36 UTC (rev 38644)
@@ -38,7 +38,11 @@
map.put( "max connections", 25);
map.put( "min connections", 10);
map.put( "connection timeout", 5);
- map.put( "validating connections", true);
+
+Connection validation is on by default, it takes a small toll to make sure the connection is still valid before using it (e.g., make sure the DBMS did not drop it due to a server side timeout).
+If you want to get extra performance and you're sure the connections will never be dropped you can disable connection validation with::
+
+ map.put( "validating connections", false);
Connection Parameters
^^^^^^^^^^^^^^^^^^^^^
Modified: trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStoreFactory.java
===================================================================
--- trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStoreFactory.java 2012-03-25 09:40:50 UTC (rev 38643)
+++ trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCDataStoreFactory.java 2012-03-25 09:52:36 UTC (rev 38644)
@@ -91,7 +91,7 @@
/** If connections should be validated before using them */
public static final Param VALIDATECONN = new Param("validate connections", Boolean .class,
- "check connection is alive before using it", false, Boolean.FALSE);
+ "check connection is alive before using it", false, Boolean.TRUE);
/** If connections should be validated before using them */
public static final Param FETCHSIZE = new Param("fetch size", Integer.class,
|
|
From: <svn...@os...> - 2012-03-25 09:40:57
|
Author: aaime
Date: 2012-03-25 02:40:50 -0700 (Sun, 25 Mar 2012)
New Revision: 38643
Modified:
trunk/modules/library/main/src/main/java/org/geotools/feature/collection/SubFeatureList.java
Log:
[GEOT-3244] NPE raised from SubFeatureList when sorting
Modified: trunk/modules/library/main/src/main/java/org/geotools/feature/collection/SubFeatureList.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/feature/collection/SubFeatureList.java 2012-03-24 20:27:03 UTC (rev 38642)
+++ trunk/modules/library/main/src/main/java/org/geotools/feature/collection/SubFeatureList.java 2012-03-25 09:40:50 UTC (rev 38643)
@@ -26,7 +26,9 @@
import java.util.Set;
import org.geotools.data.simple.SimpleFeatureCollection;
+import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.factory.CommonFactoryFinder;
+import org.geotools.util.SoftValueHashMap;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
@@ -54,16 +56,16 @@
public SubFeatureList(SimpleFeatureCollection list, SortBy sort ){
this( list, Filter.INCLUDE, sort );
}
+
/**
- * Create a simple SubFeatureList with the provided
- * filter.
- *
- * @param filter
- */
- public SubFeatureList(SimpleFeatureCollection list, Filter filter, SortBy subSort) {
- super( list, filter );
-
- if( subSort == null || subSort.equals( SortBy.NATURAL_ORDER ) ){
+ * Create a simple SubFeatureList with the provided filter.
+ *
+ * @param filter
+ */
+ public SubFeatureList(SimpleFeatureCollection list, Filter filter, SortBy subSort) {
+ super(list, filter);
+
+ if( subSort == null || subSort.equals( SortBy.NATURAL_ORDER ) ) {
sort = Collections.emptyList();
} else {
sort = new ArrayList<SortBy>();
@@ -73,7 +75,7 @@
}
sort.add( subSort );
}
- index = null;
+ index = createIndex();
}
public SubFeatureList(SimpleFeatureCollection list, List order) {
@@ -92,32 +94,31 @@
* @throws IndexOutOfBoundsException
* if index is not between 0 and size
*/
- public SimpleFeature get( int position ) {
+ public SimpleFeature get(int position) {
+ FeatureId fid = index.get(position);
if( collection instanceof RandomFeatureAccess){
RandomFeatureAccess random = (RandomFeatureAccess) collection;
- FeatureId fid = index().get( position);
return random.getFeatureMember( fid.getID() );
}
- Iterator<SimpleFeature> it = iterator();
+ SimpleFeatureIterator it = collection.features();
try {
- for( int i=0; it.hasNext(); i++){
+ while(it.hasNext()) {
SimpleFeature feature = (SimpleFeature) it.next();
- if( i == position ){
+ if(id.equals(feature.getID())) {
return feature;
}
}
throw new IndexOutOfBoundsException();
+ } finally {
+ it.close();
}
- finally {
- close( it );
- }
}
/** Lazy create a filter based on index */
protected Filter createFilter() {
FilterFactory ff = CommonFactoryFinder.getFilterFactory(null);
Set featureIds = new HashSet();
- for(Iterator it = index().iterator(); it.hasNext();){
+ for(Iterator it = index.iterator(); it.hasNext();){
featureIds.add(ff.featureId((String) it.next()));
}
Id fids = ff.id(featureIds);
@@ -125,30 +126,24 @@
return fids;
}
- protected List<FeatureId> index(){
- if( index == null ){
- index = createIndex();
- }
- return index;
- }
-
/** Put this SubFeatureList in touch with its inner index */
- protected List<FeatureId> createIndex(){
+ protected List<FeatureId> createIndex() {
List<FeatureId> fids = new ArrayList<FeatureId>();
- Iterator<SimpleFeature> it = collection.iterator();
+ SimpleFeatureIterator it = collection.features();
try {
- while( it.hasNext() ){
+ while(it.hasNext()) {
SimpleFeature feature = it.next();
if( filter.evaluate(feature ) ){
fids.add( feature.getIdentifier() );
}
}
if( sort != null && !sort.isEmpty()){
- final SortBy initialOrder = (SortBy) sort.get( sort.size() -1 );
- Collections.sort( fids, new Comparator<FeatureId>(){
+ final SortBy initialOrder = (SortBy) sort.get( sort.size() -1 );
+ final FeatureIdAccessor idAccessor = new FeatureIdAccessor(true);
+ Collections.sort(fids, new Comparator<FeatureId>() {
public int compare( FeatureId key1, FeatureId key2 ) {
- SimpleFeature feature1 = getFeatureMember( key1.getID() );
- SimpleFeature feature2 = getFeatureMember( key2.getID() );
+ SimpleFeature feature1 = idAccessor.getFeature( key1.getID() );
+ SimpleFeature feature2 = idAccessor.getFeature( key2.getID() );
int compare = compare( feature1, feature2, initialOrder );
if( compare == 0 && sort.size() > 1 ){
@@ -158,23 +153,33 @@
}
return compare;
}
+
@SuppressWarnings("unchecked")
protected int compare( SimpleFeature feature1, SimpleFeature feature2, SortBy order){
PropertyName name = order.getPropertyName();
Comparable value1 = (Comparable) name.evaluate( feature1 );
Comparable value2 = (Comparable) name.evaluate( feature2 );
-
+
+ if(value1 == value2) {
+ return 0;
+ }
if( order.getSortOrder() == SortOrder.ASCENDING ){
+ if(value1 == null) {
+ return -1;
+ }
return value1.compareTo( value2 );
+ } else {
+ if(value2 == null) {
+ return -1;
+ }
+ return value2.compareTo( value1 );
}
- else return value2.compareTo( value1 );
}
});
}
+ } finally {
+ it.close();
}
- finally {
- collection.close( it );
- }
return fids;
}
@@ -202,18 +207,19 @@
*/
public boolean add(SimpleFeature feature) {
boolean added = collection.add( feature );
- if( added ){
- index().add( feature.getIdentifier() );
+ if(added){
+ index.add( feature.getIdentifier() );
}
return true;
}
- public int indexOf(SimpleFeature feature) {
- return index().indexOf( feature.getIdentifier() );
- }
- public int lastIndexOf(SimpleFeature feature) {
- return index().lastIndexOf( feature.getIdentifier() );
- }
+ public int indexOf(SimpleFeature feature) {
+ return index.indexOf(feature.getIdentifier());
+ }
+
+ public int lastIndexOf(SimpleFeature feature) {
+ return index.lastIndexOf(feature.getIdentifier());
+ }
//
// Feature Collection methods
@@ -234,21 +240,19 @@
}
return new SubFeatureList(collection, ff.and( filter, subfilter), sort.get(0) );
}
+
//
// RandomFeatureAccess
//
public SimpleFeature getFeatureMember( String id ) throws NoSuchElementException {
- int position = index.indexOf( id );
- if( position == -1){
+ int position = index.indexOf(ff.featureId(id));
+ if( position == -1) {
throw new NoSuchElementException(id);
}
- if( collection instanceof RandomFeatureAccess ){
- RandomFeatureAccess random = (RandomFeatureAccess) collection;
- random.getFeatureMember( id );
- }
- return (SimpleFeature) get( position );
+ return new FeatureIdAccessor(false).getFeature(id);
}
+
public SimpleFeature removeFeatureMember( String id ) {
int position = index.indexOf( ff.featureId(id) );
if( position == -1){
@@ -261,26 +265,17 @@
}
return (SimpleFeature) remove( position );
}
- public SimpleFeature remove( int position ){
+
+ public SimpleFeature remove(int position) {
+ FeatureId fid = index.get(position);
if( collection instanceof RandomFeatureAccess){
RandomFeatureAccess random = (RandomFeatureAccess) collection;
- FeatureId fid = index().get( position );
+
return random.removeFeatureMember( fid.getID() );
}
- Iterator<SimpleFeature> it = iterator();
- try {
- for( int i=0; it.hasNext(); i++){
- SimpleFeature feature = (SimpleFeature) it.next();
- if( i == position ){
- collection.remove( feature );
- return feature;
- }
- }
- throw new IndexOutOfBoundsException();
- }
- finally {
- close( it );
- }
+ SimpleFeature feature = new FeatureIdAccessor(false).getFeature(id);
+ collection.remove(feature);
+ return feature;
}
/**
@@ -298,20 +293,78 @@
}
private class SortedIteratory implements Iterator<SimpleFeature> {
- Iterator<FeatureId> iterator = index().iterator();
+ Iterator<FeatureId> iterator = index.iterator();
String id;
+ FeatureIdAccessor idAccessor = new FeatureIdAccessor(true);
+
public boolean hasNext() {
return iterator != null && iterator.hasNext();
}
public SimpleFeature next() {
FeatureId fid = iterator.next();
id = fid.getID();
- return getFeatureMember( id );
+ return idAccessor.getFeature(id);
}
public void remove() {
removeFeatureMember(id);
}
}
+
+ private class FeatureIdAccessor {
+ SoftValueHashMap<String, SimpleFeature> featureCache;
+ private boolean cacheFeatures;
+
+ public FeatureIdAccessor(boolean cacheFeatures) {
+ this.cacheFeatures = cacheFeatures;
+ if(cacheFeatures) {
+ featureCache = new SoftValueHashMap<String, SimpleFeature>();
+ }
+ }
+
+ protected SimpleFeature getFeature(String id) {
+ if(collection instanceof RandomFeatureAccess) {
+ RandomFeatureAccess random = (RandomFeatureAccess) collection;
+ return random.getFeatureMember( id );
+ } else if(cacheFeatures) {
+ // check in the cache
+ SimpleFeature result = featureCache.get(id);
+ if(result != null) {
+ return result;
+ }
+
+ // sigh, full scan needed
+ SimpleFeatureIterator it = collection.features();
+ try {
+ while(it.hasNext()) {
+ SimpleFeature feature = it.next();
+ featureCache.put(id, feature);
+ if(id.equals(feature.getID())) {
+ return feature;
+ }
+ }
+ } finally {
+ it.close();
+ }
+
+ throw new RuntimeException("Could not find feature with id " + id);
+ } else {
+ // full scan...
+ SimpleFeatureIterator it = collection.features();
+ try {
+ while(it.hasNext()) {
+ SimpleFeature feature = it.next();
+ if(id.equals(feature.getID())) {
+ return feature;
+ }
+ }
+ } finally {
+ it.close();
+ }
+
+ throw new RuntimeException("Could not find feature with id " + id);
+ }
+ }
+ }
}
|
|
From: <svn...@os...> - 2012-03-24 20:27:11
|
Author: aaime
Date: 2012-03-24 13:27:03 -0700 (Sat, 24 Mar 2012)
New Revision: 38642
Modified:
trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
Log:
[GEOT-4078] Selects all when retrieving an SRID, patch by Ken Bisland
Modified: trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-03-24 20:24:25 UTC (rev 38641)
+++ trunk/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-03-24 20:27:03 UTC (rev 38642)
@@ -152,7 +152,7 @@
public Integer getGeometrySRID(String schemaName, String tableName,
String columnName, Connection cx) throws SQLException {
- StringBuffer sql = new StringBuffer("SELECT ");
+ StringBuffer sql = new StringBuffer("SELECT TOP 1 ");
encodeColumnName(null, columnName, sql);
sql.append( ".STSrid");
|
|
From: <svn...@os...> - 2012-03-24 20:24:33
|
Author: aaime
Date: 2012-03-24 13:24:25 -0700 (Sat, 24 Mar 2012)
New Revision: 38641
Modified:
branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
Log:
[GEOT-4078] Selects all when retrieving an SRID, patch by Ken Bisland
Modified: branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java
===================================================================
--- branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-03-21 06:22:23 UTC (rev 38640)
+++ branches/2.7.x/modules/plugin/jdbc/jdbc-sqlserver/src/main/java/org/geotools/data/sqlserver/SQLServerDialect.java 2012-03-24 20:24:25 UTC (rev 38641)
@@ -151,7 +151,7 @@
public Integer getGeometrySRID(String schemaName, String tableName,
String columnName, Connection cx) throws SQLException {
- StringBuffer sql = new StringBuffer("SELECT ");
+ StringBuffer sql = new StringBuffer("SELECT TOP 1 ");
encodeColumnName(columnName, sql);
sql.append( ".STSrid");
|
|
From: <svn...@os...> - 2012-03-21 06:22:31
|
Author: bencaradocdavies
Date: 2012-03-20 23:22:23 -0700 (Tue, 20 Mar 2012)
New Revision: 38640
Added:
trunk/modules/extension/app-schema/app-schema-resolver/src/test/java/org/geotools/xml/AppSchemaValidatorDemo.java
trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/
trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/app-schema-cache/
trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/app-schema-cache/README.txt
trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/file-to-be-validated.xml
Modified:
trunk/modules/extension/app-schema/app-schema-resolver/src/main/java/org/geotools/xml/AppSchemaResolver.java
Log:
Made app-schema-resolver classpath resolution of schemas optional. Added AppSchemaValidatorDemo for validation with downloaded schemas only.
Modified: trunk/modules/extension/app-schema/app-schema-resolver/src/main/java/org/geotools/xml/AppSchemaResolver.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema-resolver/src/main/java/org/geotools/xml/AppSchemaResolver.java 2012-03-19 20:24:06 UTC (rev 38639)
+++ trunk/modules/extension/app-schema/app-schema-resolver/src/main/java/org/geotools/xml/AppSchemaResolver.java 2012-03-21 06:22:23 UTC (rev 38640)
@@ -60,6 +60,11 @@
private AppSchemaCatalog catalog;
/**
+ * True if schemas can be resolved on the classpath.
+ */
+ private boolean classpath = true;
+
+ /**
* Cache of schemas with optional downloading support(null if not present).
*/
private AppSchemaCache cache;
@@ -77,14 +82,26 @@
* Constructor.
*
* @param catalog
+ * @param classpath whether schemas can be located on the classpath
* @param cache
*/
- public AppSchemaResolver(AppSchemaCatalog catalog, AppSchemaCache cache) {
+ public AppSchemaResolver(AppSchemaCatalog catalog, boolean classpath, AppSchemaCache cache) {
this.catalog = catalog;
+ this.classpath = classpath;
this.cache = cache;
}
/**
+ * Constructor.
+ *
+ * @param catalog
+ * @param cache
+ */
+ public AppSchemaResolver(AppSchemaCatalog catalog, AppSchemaCache cache) {
+ this(catalog, true, cache);
+ }
+
+ /**
* Convenience constructor for a resolver with neither catalog nor cache (just classpath).
*/
public AppSchemaResolver() {
@@ -175,7 +192,7 @@
resolvedLocation = catalog.resolveLocation(location);
}
// Look on classpath.
- if (resolvedLocation == null) {
+ if (resolvedLocation == null && classpath) {
resolvedLocation = resolveClasspathLocation(location);
}
// Use download cache.
Added: trunk/modules/extension/app-schema/app-schema-resolver/src/test/java/org/geotools/xml/AppSchemaValidatorDemo.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema-resolver/src/test/java/org/geotools/xml/AppSchemaValidatorDemo.java (rev 0)
+++ trunk/modules/extension/app-schema/app-schema-resolver/src/test/java/org/geotools/xml/AppSchemaValidatorDemo.java 2012-03-21 06:22:23 UTC (rev 38640)
@@ -0,0 +1,94 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2012, 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.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * <p>
+ * A demonstration of schema-validation in which XML schemas are downloaded from the network.
+ * Schemas on the classpath are not used.
+ * </p>
+ *
+ * <p>
+ * This demo validates the content of
+ * <code>src/test/resources/test-data/validator-demo/file-to-be-validated.xml</code> against the
+ * schemas declared in its <code>schemaLocation</code>. The schema-validation should report two
+ * validation failures to stderr when run as an application in Eclipse.
+ * </p>
+ *
+ * <p>
+ * To validate any other XML document with an XML Schema grammer, replace the content of
+ * <code>src/test/resources/test-data/validator-demo/file-to-be-validated.xml</code> with the
+ * document to be validated and run this class as an application in Eclipse. Validation requires the
+ * presence of a <code>schemaLocation</code> in the instance document.
+ * </p>
+ *
+ * <p>
+ * Schemas required for validation will be downloaded from the network and placed in
+ * <code>target/test-classes/test-data/validator-demo/app-schema-cache</code>. The cache is
+ * configured by the existence of
+ * <code>src/test/resources/test-data/validator-demo/app-schema-cache</code>, which is copied to
+ * <code>target/test-classes</code> by Eclipse and discovered by searching the ancestor directories
+ * of the file under validation (also copied and found earlier on the classpath).
+ * </p>
+ *
+ * @author Ben Caradoc-Davies (CSIRO Earth Science and Resource Engineering)
+ */
+public class AppSchemaValidatorDemo {
+
+ /**
+ * The classpath resource to be schema-validated.
+ */
+ public static final String RESOURCE = "/test-data/validator-demo/file-to-be-validated.xml";
+
+ /**
+ * Perform the schema-validation.
+ *
+ * @param args
+ * ignored
+ */
+ public static void main(String[] args) {
+ // download and cache schemas using app-schema-cache discovered from resource path
+ AppSchemaCache cache = AppSchemaCache
+ .buildAutomaticallyConfiguredUsingFileUrl(AppSchemaValidatorDemo.class
+ .getResource(RESOURCE));
+ // no classpath resolution of schemas; cached downloads only
+ AppSchemaResolver resolver = new AppSchemaResolver(null, false, cache);
+ AppSchemaValidator validator = AppSchemaValidator.buildValidator(resolver);
+ InputStream input = null;
+ try {
+ input = AppSchemaValidator.class.getResourceAsStream(RESOURCE);
+ validator.parse(input);
+ // validation failures result in an RuntimeException that lists them
+ validator.checkForFailures();
+ System.err.println("Successful schema-validation of " + RESOURCE);
+ } finally {
+ if (input != null) {
+ try {
+ input.close();
+ } catch (IOException e) {
+ // we tried
+ }
+ }
+ }
+
+ }
+
+}
Property changes on: trunk/modules/extension/app-schema/app-schema-resolver/src/test/java/org/geotools/xml/AppSchemaValidatorDemo.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Id URL
Added: svn:eol-style
+ native
Added: trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/app-schema-cache/README.txt
===================================================================
--- trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/app-schema-cache/README.txt (rev 0)
+++ trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/app-schema-cache/README.txt 2012-03-21 06:22:23 UTC (rev 38640)
@@ -0,0 +1,9 @@
+The presence of the folder "app-schema-cache" triggers automatic configuration
+of the AppSchemaCache used by AppSchemaValidationDemo.
+
+If you are looking for downloaded schemas, they should be in the copy of this
+folder in target/test-classes/test-data/validator-demo/app-schema-cache
+because file-to-be-validated.xml is loaded from the classpath before the
+source path.
+
+See AppSchemaValidatorDemo for more.
\ No newline at end of file
Property changes on: trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/app-schema-cache/README.txt
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:keywords
+ Id URL
Added: svn:eol-style
+ native
Added: trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/file-to-be-validated.xml
===================================================================
--- trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/file-to-be-validated.xml (rev 0)
+++ trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/file-to-be-validated.xml 2012-03-21 06:22:23 UTC (rev 38640)
@@ -0,0 +1,805 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- The content of this file undergoes schema-validation by AppSchemaValidationDemo. -->
+<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:gsml="urn:cgi:xmlns:CGI:GeoSciML:2.0" xmlns:gml="http://www.opengis.net/gml" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:er="urn:cgi:xmlns:GGIC:EarthResource:1.1" xsi:schemaLocation="urn:cgi:xmlns:GGIC:EarthResource:1.1 http://www.earthresourceml.org/earthresourceml/1.1/xsd/earthResource.xsd http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" numberOfFeatures="10">
+<gml:boundedBy>
+<gml:Envelope srsName="EPSG:4326">
+<gml:lowerCorner>8.8888 -8.8888</gml:lowerCorner>
+<gml:upperCorner>8.8888 -8.8888</gml:upperCorner>
+</gml:Envelope>
+</gml:boundedBy>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.372122">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:372122</gml:name>
+<gml:name codeSpace="http://www.example.org/earth-resources">Zzzz</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.372122">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:372122</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">200</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.372122"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:width>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Unknown</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:classification>
+<er:MineralDepositModel>
+<er:mineralDepositGroup codeSpace="http://www.example.org/earth-resources">Unknown</er:mineralDepositGroup>
+</er:MineralDepositModel>
+</er:classification>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:372122:au"/>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.366920">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:366920</gml:name>
+<gml:name codeSpace="http://www.example.org/earth-resources">Example River</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.366920">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:366920</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.366920"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:width>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Placer - modern</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:366920:au"/>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.367108">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:367108</gml:name>
+<gml:name codeSpace="http://www.example.org/earth-resources">Lower Example River</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.367108">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:367108</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">2000</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.367108"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:width>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Vein hosted - general</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:classification>
+<er:MineralDepositModel>
+<er:mineralDepositGroup codeSpace="http://www.example.org/earth-resources">Unknown</er:mineralDepositGroup>
+</er:MineralDepositModel>
+</er:classification>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:367108:au"/>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.366991">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:366991</gml:name>
+<gml:name codeSpace="http://www.example.org/earth-resources">Example River</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.366991">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:366991</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">55</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.366991"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:width>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Vein hosted - general</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:classification>
+<er:MineralDepositModel>
+<er:mineralDepositGroup codeSpace="http://www.example.org/earth-resources">Unknown</er:mineralDepositGroup>
+</er:MineralDepositModel>
+</er:classification>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:366991:au"/>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.368989">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:368989</gml:name>
+<gml:name codeSpace="http://www.example.org/earth-resources">Example-Example Goldfield</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.368989">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:368989</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">7</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.368989"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:width>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Unknown</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:classification>
+<er:MineralDepositModel>
+<er:mineralDepositGroup codeSpace="http://www.example.org/earth-resources">Unknown</er:mineralDepositGroup>
+</er:MineralDepositModel>
+</er:classification>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:368989:au"/>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.372258">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:372258</gml:name>
+<gml:name codeSpace="http://www.example.org/earth-resources">Fiction</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.372258">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:372258</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">250</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.372258"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:width>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Placer - modern</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:classification>
+<er:MineralDepositModel>
+<er:mineralDepositGroup codeSpace="http://www.example.org/earth-resources">Alluvial Au</er:mineralDepositGroup>
+</er:MineralDepositModel>
+</er:classification>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:372258:au"/>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.875599">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:875599</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.875599">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:875599</gml:name>
+<!-- intentional error for testing: positionalAccuracy should be after observationMethod -->
+<gsml:positionalAccuracy>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:positionalAccuracy>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.875599"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:depth>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:depth>
+<er:length>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:length>
+<er:width>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Primary</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:linearOrientation>
+<gsml:CGI_LinearOrientation>
+<gsml:plunge>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::deg">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:plunge>
+<gsml:trend>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::deg">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:trend>
+</gsml:CGI_LinearOrientation>
+</er:linearOrientation>
+<er:planarOrientation>
+<gsml:CGI_PlanarOrientation>
+<gsml:convention>dip dip direction</gsml:convention>
+<gsml:azimuth>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::deg">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:azimuth>
+<gsml:dip>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::deg">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:dip>
+<gsml:polarity>not applicable</gsml:polarity>
+</gsml:CGI_PlanarOrientation>
+</er:planarOrientation>
+<er:classification>
+<er:MineralDepositModel>
+<er:mineralDepositGroup codeSpace="http://www.example.org/earth-resources">Mesozonal orogenic Au</er:mineralDepositGroup>
+</er:MineralDepositModel>
+</er:classification>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:875599:au"/>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.378079">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:378079</gml:name>
+<gml:name codeSpace="http://www.example.org/earth-resources">Fabricated</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.378079">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:378079</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">5</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.378079"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:depth>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">37.9</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:depth>
+<er:width>
+<gsml:CGI_NumericRange>
+<gsml:lower>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">34.4</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:lower>
+<gsml:upper>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">49.7</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:upper>
+</gsml:CGI_NumericRange>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Placer - ancient & buried</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:classification>
+<er:MineralDepositModel>
+<er:mineralDepositGroup codeSpace="http://www.example.org/earth-resources">Alluvial Au</er:mineralDepositGroup>
+</er:MineralDepositModel>
+</er:classification>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:378079:au"/>
+<er:composition>
+<er:EarthResourceMaterial>
+<er:earthResourceMaterialRole>unspecified</er:earthResourceMaterialRole>
+<er:material>
+<gsml:RockMaterial>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:consolidationDegree>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:consolidationDegree>
+<gsml:lithology xlink:href="urn:cgi:classifier:CGI:SimpleLithology:2008:gravel"/>
+</gsml:RockMaterial>
+</er:material>
+<er:proportion>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</er:proportion>
+</er:EarthResourceMaterial>
+</er:composition>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:23418"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21381"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21380"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21379"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21378"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21377"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21376"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21375"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21374"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21373"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21372"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21371"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21370"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21369"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21368"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21367"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21366"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21365"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21364"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21363"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21362"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21361"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21360"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21359"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21358"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21357"/>
+<er:resourceExtraction xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MiningActivity:378079:21356"/>
+<er:child xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MineralOccurrence:376747"/>
+<er:child xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MineralOccurrence:377559"/>
+<er:child xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:MineralOccurrence:377987"/>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.365344">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:365344</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.365344">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:365344</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">5</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.365344"/>
+<gsml:shape>
+<gml:Point srsName="EPSG:4326">
+<gml:pos>8.8888 -8.8888</gml:pos>
+</gml:Point>
+</gsml:shape>
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:length>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">900</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:length>
+<er:width>
+<gsml:CGI_NumericRange>
+<gsml:lower>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:lower>
+<gsml:upper>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">7.6</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:upper>
+</gsml:CGI_NumericRange>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Vein hosted - general</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:planarOrientation>
+<gsml:CGI_PlanarOrientation>
+<gsml:convention>dip dip direction</gsml:convention>
+<gsml:azimuth>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::deg">325</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:azimuth>
+<gsml:polarity>not applicable</gsml:polarity>
+</gsml:CGI_PlanarOrientation>
+</er:planarOrientation>
+<er:classification>
+<er:MineralDepositModel>
+<er:mineralDepositGroup codeSpace="http://www.example.org/earth-resources">Unknown</er:mineralDepositGroup>
+</er:MineralDepositModel>
+</er:classification>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:365344:cu"/>
+<er:composition>
+<er:EarthResourceMaterial>
+<er:earthResourceMaterialRole>unspecified</er:earthResourceMaterialRole>
+<er:material>
+<gsml:RockMaterial>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:consolidationDegree>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:consolidationDegree>
+<gsml:lithology xlink:href="urn:cgi:classifier:CGI:SimpleLithology:2008:granodiorite"/>
+</gsml:RockMaterial>
+</er:material>
+<er:proportion>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</er:proportion>
+</er:EarthResourceMaterial>
+</er:composition>
+<er:type>occurrence</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+<gml:featureMember>
+<er:MineralOccurrence gml:id="er.mineraloccurrence.365023">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MineralOccurrence:365023</gml:name>
+<gml:name codeSpace="http://www.example.org/earth-resources">Sanitised</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:occurrence>
+<gsml:MappedFeature gml:id="gsml.mappedfeature.mineraloccurrence.365023">
+<gml:name codeSpace="http://www.ietf.org/rfc/rfc2141">urn:cgi:feature:Example:MappedFeature:MineralOccurrence:365023</gml:name>
+<gsml:observationMethod>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:observationMethod>
+<gsml:positionalAccuracy>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">300</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:positionalAccuracy>
+<gsml:samplingFrame xlink:href="urn:cgi:feature:CGI:EarthNaturalSurface"/>
+<gsml:specification xlink:href="#er.mineraloccurrence.365023"/>
+<!-- intentional error for testing: shape is missing -->
+</gsml:MappedFeature>
+</gsml:occurrence>
+<er:dimension>
+<er:EarthResourceDimension>
+<er:area>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::har">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:area>
+<er:width>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::m">0</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</er:width>
+</er:EarthResourceDimension>
+</er:dimension>
+<er:form>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://www.example.org/earth-resources">Vein hosted - general</gsml:value>
+</gsml:CGI_TermValue>
+</er:form>
+<er:planarOrientation>
+<gsml:CGI_PlanarOrientation>
+<gsml:convention>dip dip direction</gsml:convention>
+<gsml:azimuth>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::deg">12</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:azimuth>
+<gsml:dip>
+<gsml:CGI_NumericValue>
+<gsml:principalValue uom="urn:ogc:def:uom:UCUM::deg">55</gsml:principalValue>
+</gsml:CGI_NumericValue>
+</gsml:dip>
+<gsml:polarity>not applicable</gsml:polarity>
+</gsml:CGI_PlanarOrientation>
+</er:planarOrientation>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:365023:tin"/>
+<er:commodityDescription xlink:href="http://services.example.org/EarthResourceML/1.1/urn/?uri=urn:cgi:feature:Example:Commodity:365023:tunx"/>
+<er:composition>
+<er:EarthResourceMaterial>
+<er:earthResourceMaterialRole>unspecified</er:earthResourceMaterialRole>
+<er:material>
+<gsml:RockMaterial>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:consolidationDegree>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:consolidationDegree>
+<gsml:lithology xlink:href="urn:cgi:classifier:CGI:SimpleLithology:2008:granodiorite"/>
+</gsml:RockMaterial>
+</er:material>
+<er:proportion>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</er:proportion>
+</er:EarthResourceMaterial>
+</er:composition>
+<er:composition>
+<er:EarthResourceMaterial>
+<er:earthResourceMaterialRole>unspecified</er:earthResourceMaterialRole>
+<er:material>
+<gsml:RockMaterial>
+<gsml:purpose>typicalNorm</gsml:purpose>
+<gsml:consolidationDegree>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</gsml:consolidationDegree>
+<gsml:lithology xlink:href="urn:cgi:classifier:CGI:SimpleLithology:2008:schist"/>
+</gsml:RockMaterial>
+</er:material>
+<er:proportion>
+<gsml:CGI_TermValue>
+<gsml:value codeSpace="http://urn.opengis.net/">urn:ogc:def:nil:OGC::missing</gsml:value>
+</gsml:CGI_TermValue>
+</er:proportion>
+</er:EarthResourceMaterial>
+</er:composition>
+<er:type>mineral deposit</er:type>
+</er:MineralOccurrence>
+</gml:featureMember>
+</wfs:FeatureCollection>
\ No newline at end of file
Property changes on: trunk/modules/extension/app-schema/app-schema-resolver/src/test/resources/test-data/validator-demo/file-to-be-validated.xml
___________________________________________________________________
Added: svn:mime-type
+ text/xml
Added: svn:keywords
+ Id URL
Added: svn:eol-style
+ native
|
|
From: <svn...@os...> - 2012-03-19 20:24:13
|
Author: aaime
Date: 2012-03-19 13:24:06 -0700 (Mon, 19 Mar 2012)
New Revision: 38639
Modified:
branches/2.7.x/modules/library/render/src/main/java/org/geotools/renderer/style/SLDStyleFactory.java
branches/2.7.x/modules/library/render/src/test/java/org/geotools/renderer/style/SLDStyleFactoryTest.java
Log:
[GEOT-4085] SLDStyleFactory will loop indefinitely trying to transform external graphics without a format
Modified: branches/2.7.x/modules/library/render/src/main/java/org/geotools/renderer/style/SLDStyleFactory.java
===================================================================
--- branches/2.7.x/modules/library/render/src/main/java/org/geotools/renderer/style/SLDStyleFactory.java 2012-03-19 20:22:48 UTC (rev 38638)
+++ branches/2.7.x/modules/library/render/src/main/java/org/geotools/renderer/style/SLDStyleFactory.java 2012-03-19 20:24:06 UTC (rev 38639)
@@ -1218,10 +1218,14 @@
Iterator<ExternalGraphicFactory> it = DynamicSymbolFactoryFinder
.getExternalGraphicFactories();
while (it.hasNext()) {
+ ExternalGraphicFactory egf = it.next();
try {
- Expression formatExpression = ExpressionExtractor.extractCqlExpressions(eg.getFormat());
- String format = formatExpression.evaluate(feature, String.class);
- Icon icon = it.next().getIcon((Feature) feature, location, format, toImageSize(size));
+ String format = null;
+ if(eg.getFormat() != null) {
+ Expression formatExpression = ExpressionExtractor.extractCqlExpressions(eg.getFormat());
+ format = formatExpression.evaluate(feature, String.class);
+ }
+ Icon icon = egf.getIcon((Feature) feature, location, format, toImageSize(size));
if (icon != null) {
return icon;
}
Modified: branches/2.7.x/modules/library/render/src/test/java/org/geotools/renderer/style/SLDStyleFactoryTest.java
===================================================================
--- branches/2.7.x/modules/library/render/src/test/java/org/geotools/renderer/style/SLDStyleFactoryTest.java 2012-03-19 20:22:48 UTC (rev 38638)
+++ branches/2.7.x/modules/library/render/src/test/java/org/geotools/renderer/style/SLDStyleFactoryTest.java 2012-03-19 20:24:06 UTC (rev 38639)
@@ -357,4 +357,14 @@
ms = (MarkStyle2D) sld.createPointStyle(feature, symb, range);
assertTrue(MarkStyle2D.isMaxMarkSizeEnabled());
}
+
+
+ public void testInfiniteLoopAvoidance() throws Exception {
+ PointSymbolizer symb = sf.createPointSymbolizer();
+ ExternalGraphic eg = sf.createExternalGraphic("http://foo.com/invalid_or_missing_image_url", null);
+ symb.getGraphic().graphicalSymbols().add(eg);
+
+ IconStyle2D icon = (IconStyle2D) sld.createPointStyle(feature, symb, range);
+ assertNull(icon);
+ }
}
|
|
From: <svn...@os...> - 2012-03-19 20:22:55
|
Author: aaime
Date: 2012-03-19 13:22:48 -0700 (Mon, 19 Mar 2012)
New Revision: 38638
Modified:
trunk/modules/library/render/src/main/java/org/geotools/renderer/style/SLDStyleFactory.java
trunk/modules/library/render/src/test/java/org/geotools/renderer/style/SLDStyleFactoryTest.java
Log:
[GEOT-4085] SLDStyleFactory will loop indefinitely trying to transform external graphics without a format
Modified: trunk/modules/library/render/src/main/java/org/geotools/renderer/style/SLDStyleFactory.java
===================================================================
--- trunk/modules/library/render/src/main/java/org/geotools/renderer/style/SLDStyleFactory.java 2012-03-19 16:19:55 UTC (rev 38637)
+++ trunk/modules/library/render/src/main/java/org/geotools/renderer/style/SLDStyleFactory.java 2012-03-19 20:22:48 UTC (rev 38638)
@@ -1219,10 +1219,14 @@
Iterator<ExternalGraphicFactory> it = DynamicSymbolFactoryFinder
.getExternalGraphicFactories();
while (it.hasNext()) {
+ ExternalGraphicFactory egf = it.next();
try {
- Expression formatExpression = ExpressionExtractor.extractCqlExpressions(eg.getFormat());
- String format = formatExpression.evaluate(feature, String.class);
- Icon icon = it.next().getIcon((Feature) feature, location, format, toImageSize(size));
+ String format = null;
+ if(eg.getFormat() != null) {
+ Expression formatExpression = ExpressionExtractor.extractCqlExpressions(eg.getFormat());
+ format = formatExpression.evaluate(feature, String.class);
+ }
+ Icon icon = egf.getIcon((Feature) feature, location, format, toImageSize(size));
if (icon != null) {
return icon;
}
Modified: trunk/modules/library/render/src/test/java/org/geotools/renderer/style/SLDStyleFactoryTest.java
===================================================================
--- trunk/modules/library/render/src/test/java/org/geotools/renderer/style/SLDStyleFactoryTest.java 2012-03-19 16:19:55 UTC (rev 38637)
+++ trunk/modules/library/render/src/test/java/org/geotools/renderer/style/SLDStyleFactoryTest.java 2012-03-19 20:22:48 UTC (rev 38638)
@@ -358,4 +358,14 @@
ms = (MarkStyle2D) sld.createPointStyle(feature, symb, range);
assertTrue(MarkStyle2D.isMaxMarkSizeEnabled());
}
+
+
+ public void testInfiniteLoopAvoidance() throws Exception {
+ PointSymbolizer symb = sf.createPointSymbolizer();
+ ExternalGraphic eg = sf.createExternalGraphic("http://foo.com/invalid_or_missing_image_url", null);
+ symb.getGraphic().graphicalSymbols().add(eg);
+
+ IconStyle2D icon = (IconStyle2D) sld.createPointStyle(feature, symb, range);
+ assertNull(icon);
+ }
}
|
Author: aaime
Date: 2012-03-19 09:19:55 -0700 (Mon, 19 Mar 2012)
New Revision: 38637
Removed:
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractGetExecutionStatusRequest.java
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/GetExecutionStatusRequest.java
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/GetExecutionStatusResponse.java
Modified:
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/ows/AbstractWPS.java
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPSSpecification.java
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WebProcessingService.java
trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java
Log:
[GEOT-4084] GeoTools WPS client support for asynch requests is GeoServer specific
Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/ows/AbstractWPS.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/ows/AbstractWPS.java 2012-03-19 14:36:02 UTC (rev 38636)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/ows/AbstractWPS.java 2012-03-19 16:19:55 UTC (rev 38637)
@@ -53,7 +53,7 @@
{
private static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.data.ows");
- private HTTPClient httpClient;
+ protected HTTPClient httpClient;
protected final URL serverURL;
protected C capabilities;
protected ServiceInfo info;
Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java 2012-03-19 14:36:02 UTC (rev 38636)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java 2012-03-19 16:19:55 UTC (rev 38637)
@@ -39,13 +39,10 @@
import org.geotools.data.ows.Response;
import org.geotools.data.wps.request.AbstractDescribeProcessRequest;
import org.geotools.data.wps.request.AbstractExecuteProcessRequest;
-import org.geotools.data.wps.request.AbstractGetExecutionStatusRequest;
import org.geotools.data.wps.request.DescribeProcessRequest;
import org.geotools.data.wps.request.ExecuteProcessRequest;
-import org.geotools.data.wps.request.GetExecutionStatusRequest;
import org.geotools.data.wps.response.DescribeProcessResponse;
import org.geotools.data.wps.response.ExecuteProcessResponse;
-import org.geotools.data.wps.response.GetExecutionStatusResponse;
import org.geotools.data.wps.response.WPSGetCapabilitiesResponse;
import org.geotools.ows.ServiceException;
@@ -118,13 +115,6 @@
}
@Override
- public GetExecutionStatusRequest createGetExecutionStatusRequest(URL onlineResource)
- throws UnsupportedOperationException
- {
- return new InternalGetExecutionStatusRequest(onlineResource, null);
- }
-
- @Override
public DataType createLiteralInputValue(String literalValue)
{
DataType literalInputValue = wpsFactory.createDataType();
@@ -291,27 +281,4 @@
}
- public static class InternalGetExecutionStatusRequest extends AbstractGetExecutionStatusRequest
- {
-
- /**
- * @param onlineResource
- * @param properties
- */
- public InternalGetExecutionStatusRequest(URL onlineResource, Properties properties)
- {
- super(onlineResource, properties);
- }
-
- protected void initVersion()
- {
- setProperty(VERSION, "1.0.0");
- }
-
- public Response createResponse(HTTPResponse httpResponse) throws ServiceException, IOException
- {
- return new GetExecutionStatusResponse(httpResponse);
- }
- }
-
}
Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPSSpecification.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPSSpecification.java 2012-03-19 14:36:02 UTC (rev 38636)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPSSpecification.java 2012-03-19 16:19:55 UTC (rev 38637)
@@ -27,7 +27,6 @@
import org.geotools.data.ows.Specification;
import org.geotools.data.wps.request.DescribeProcessRequest;
import org.geotools.data.wps.request.ExecuteProcessRequest;
-import org.geotools.data.wps.request.GetExecutionStatusRequest;
/**
@@ -60,9 +59,6 @@
public abstract ExecuteProcessRequest createExecuteProcessRequest(URL onlineResource)
throws UnsupportedOperationException;
- public abstract GetExecutionStatusRequest createGetExecutionStatusRequest(URL onlineResource)
- throws UnsupportedOperationException;
-
public abstract DataType createLiteralInputValue(String literalValue);
public abstract DataType createBoundingBoxInputValue(String crs, int dimensions, List<Double> lowerCorner,
Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WebProcessingService.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WebProcessingService.java 2012-03-19 14:36:02 UTC (rev 38636)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WebProcessingService.java 2012-03-19 16:19:55 UTC (rev 38637)
@@ -16,7 +16,10 @@
*/
package org.geotools.data.wps;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -43,13 +46,13 @@
import org.geotools.data.ows.AbstractWPSGetCapabilitiesResponse;
import org.geotools.data.ows.GetCapabilitiesRequest;
import org.geotools.data.ows.HTTPClient;
+import org.geotools.data.ows.HTTPResponse;
+import org.geotools.data.ows.Response;
import org.geotools.data.ows.Specification;
import org.geotools.data.wps.request.DescribeProcessRequest;
import org.geotools.data.wps.request.ExecuteProcessRequest;
-import org.geotools.data.wps.request.GetExecutionStatusRequest;
import org.geotools.data.wps.response.DescribeProcessResponse;
import org.geotools.data.wps.response.ExecuteProcessResponse;
-import org.geotools.data.wps.response.GetExecutionStatusResponse;
import org.geotools.ows.ServiceException;
import org.geotools.wps.WPS;
@@ -227,11 +230,15 @@
{
return (ExecuteProcessResponse) internalIssueRequest(request);
}
-
- public GetExecutionStatusResponse issueRequest(GetExecutionStatusRequest request) throws IOException,
- ServiceException
+
+ public ExecuteProcessResponse issueStatusRequest(URL statusURL) throws IOException, ServiceException
{
- return (GetExecutionStatusResponse) internalIssueRequest(request);
+ final HTTPResponse httpResponse;
+
+ httpResponse = httpClient.get(statusURL);
+
+ // a request with status can never use raw requests
+ return new ExecuteProcessResponse(httpResponse, false);
}
/**
@@ -285,26 +292,6 @@
return request;
}
- public GetExecutionStatusRequest createGetExecutionStatusRequest() throws UnsupportedOperationException
- {
- ProcessOfferingsType processOfferings = getCapabilities().getProcessOfferings();
- if ((processOfferings == null) || !processOfferings.eAllContents().hasNext())
- {
- throw new UnsupportedOperationException(
- "Server does not specify a GetExecutionStatus operation. Cannot be performed.");
- }
-
- URL "getexecutionstatus", capabilities, true);
- if ( null)
- {
-
- }
-
- GetExecutionStatusRequest request = getSpecification().createGetExecutionStatusRequest(onlineResource);
-
- return request;
- }
-
private WPSSpecification getSpecification()
{
return (WPSSpecification) specification;
Deleted: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractGetExecutionStatusRequest.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractGetExecutionStatusRequest.java 2012-03-19 14:36:02 UTC (rev 38636)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractGetExecutionStatusRequest.java 2012-03-19 16:19:55 UTC (rev 38637)
@@ -1,59 +0,0 @@
-/*
- * GeoTools - The Open Source Java GIS Toolkit
- * http://geotools.org
- *
- * (C) 2004-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.wps.request;
-
-import java.net.URL;
-import java.util.Properties;
-
-
-/**
- * Describes an abstract GetExecutionStatus request. Provides everything except
- * the versioning info, which subclasses must implement.
- *
- * @author afabiani
- *
- * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractGetExecutionStatusRequest $
- */
-public abstract class AbstractGetExecutionStatusRequest extends AbstractWPSRequest implements GetExecutionStatusRequest
-{
-
- /**
- * Constructs a basic GetExecutionStatusRequest, without versioning info.
- *
- * @param onlineResource the location of the request
- * @param properties a set of properties to use. Can be null.
- */
- public AbstractGetExecutionStatusRequest(URL onlineResource, Properties properties)
- {
- super(onlineResource, properties);
- }
-
- protected void initRequest()
- {
- setProperty(REQUEST, "GetExecutionStatus");
- }
-
- /**
- * @see org.geotools.data.wps.request.GetExecutionStatusRequest#setIdentifier(java.lang.String)
- */
- public void setIdentifier(String identifiers)
- {
- setProperty(IDENTIFIER, identifiers);
- }
-
- protected abstract void initVersion();
-}
Deleted: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/GetExecutionStatusRequest.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/GetExecutionStatusRequest.java 2012-03-19 14:36:02 UTC (rev 38636)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/GetExecutionStatusRequest.java 2012-03-19 16:19:55 UTC (rev 38637)
@@ -1,45 +0,0 @@
-/*
- * GeoTools - The Open Source Java GIS Toolkit
- * http://geotools.org
- *
- * (C) 2004-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.wps.request;
-
-import org.geotools.data.ows.Request;
-
-
-/**
- * Retrieves information about the given execution on
- * the WPS Server.
- *
- * The only parameter it takes is a process which it uses to
- * return the information about.
- *
- * @author afabiani
- *
- * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/GetExecutionStatusRequest.java $
- */
-public interface GetExecutionStatusRequest extends Request
-{
-
- /** Represents the PROCESS parameter */
- public static final String IDENTIFIER = "IDENTIFIER"; // $NON-NLS-1$
-
- /**
- * Sets the name of the process to look up
- *
- * @param processname A comma-delimited list of unique process names
- */
- public void setIdentifier(String processnames);
-}
Deleted: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/GetExecutionStatusResponse.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/GetExecutionStatusResponse.java 2012-03-19 14:36:02 UTC (rev 38636)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/GetExecutionStatusResponse.java 2012-03-19 16:19:55 UTC (rev 38637)
@@ -1,118 +0,0 @@
-/*
- * GeoTools - The Open Source Java GIS Toolkit
- * http://geotools.org
- *
- * (C) 2004-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.wps.response;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.xml.parsers.ParserConfigurationException;
-
-import net.opengis.ows11.ExceptionReportType;
-import net.opengis.wps10.ExecuteResponseType;
-
-import org.geotools.data.ows.HTTPResponse;
-import org.geotools.data.ows.Response;
-import org.geotools.ows.ServiceException;
-import org.geotools.wps.WPSConfiguration;
-import org.geotools.xml.Configuration;
-import org.geotools.xml.Parser;
-import org.xml.sax.SAXException;
-
-
-/**
- * Represents the response from a server after a DescribeProcess request
- * has been issued.
- *
- * @author gdavis
- *
- * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/DescribeProcessResponse.java $
- */
-public class GetExecutionStatusResponse extends Response
-{
-
- private ExecuteResponseType exeResponse;
- private ExceptionReportType excepResponse;
-
- /**
- * @param contentType
- * @param inputStream
- * @throws ServiceException
- * @throws SAXException
- */
- public GetExecutionStatusResponse(HTTPResponse httpResponse) throws IOException, ServiceException
- {
- super(httpResponse);
-
- InputStream inputStream = null;
- try
- {
- inputStream = httpResponse.getResponseStream();
-
- // Map hints = new HashMap();
- // hints.put(DocumentHandler.DEFAULT_NAMESPACE_HINT_KEY, WPSSchema.getInstance());
- Configuration config = new WPSConfiguration();
- Parser parser = new Parser(config);
-
- Object object;
- exeResponse = null;
- excepResponse = null;
- try
- {
- // object = DocumentFactory.getInstance(inputStream, hints, Level.WARNING);
- object = parser.parse(inputStream);
- }
- catch (SAXException e)
- {
- throw (IOException) new IOException().initCause(e);
- }
- catch (ParserConfigurationException e)
- {
- throw (IOException) new IOException().initCause(e);
- }
-
- // try casting the response
- if (object instanceof ExecuteResponseType)
- {
- exeResponse = (ExecuteResponseType) object;
- }
- // exception caught on server and returned
- else if (object instanceof ExceptionReportType)
- {
- excepResponse = (ExceptionReportType) object;
- }
-
- }
- finally
- {
- if (inputStream != null)
- {
- inputStream.close();
- }
- }
- }
-
- public ExecuteResponseType getExecuteResponse()
- {
- return exeResponse;
- }
-
- public ExceptionReportType getExceptionResponse()
- {
- return excepResponse;
- }
-
-}
Modified: trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java
===================================================================
--- trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java 2012-03-19 14:36:02 UTC (rev 38636)
+++ trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java 2012-03-19 16:19:55 UTC (rev 38637)
@@ -27,6 +27,7 @@
import net.opengis.ows11.ExceptionReportType;
import net.opengis.wps10.DataType;
+import net.opengis.wps10.DocumentOutputDefinitionType;
import net.opengis.wps10.ExecuteResponseType;
import net.opengis.wps10.InputDescriptionType;
import net.opengis.wps10.LiteralDataType;
@@ -36,6 +37,7 @@
import net.opengis.wps10.ProcessDescriptionType;
import net.opengis.wps10.ProcessDescriptionsType;
import net.opengis.wps10.ProcessOfferingsType;
+import net.opengis.wps10.ResponseDocumentType;
import net.opengis.wps10.ResponseFormType;
import net.opengis.wps10.WPSCapabilitiesType;
@@ -730,6 +732,7 @@
while((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
+ reader.close();
String arcgrid = sb.toString();
String expectedHeader = "NCOLS 2\n" +
"NROWS 1\n" +
@@ -815,4 +818,119 @@
assertNotNull(executeResponse.getStatus().getProcessFailed());
assertNotNull( executeResponse.getStatus().getProcessFailed().getExceptionReport());
}
+
+ /**
+ * Try to get an area grid with output in asynchronous mode
+ *
+ * @throws ServiceException
+ * @throws IOException
+ * @throws ParseException
+ */
+ public void testExecuteAsynchAreaGrid() throws ServiceException, IOException, ParseException
+ {
+
+ // don't run the test if the server is not up
+ if (fixture == null)
+ {
+ return;
+ }
+
+ if (DISABLE)
+ {
+ return;
+ }
+
+ String processIdenLocal = "gs:AreaGrid";
+
+ WPSCapabilitiesType capabilities = wps.getCapabilities();
+
+ // get the first process and execute it
+ ProcessOfferingsType processOfferings = capabilities.getProcessOfferings();
+ EList processes = processOfferings.getProcess();
+ // ProcessBriefType process = (ProcessBriefType) processes.get(0);
+
+ // does the server contain the specific process I want
+ boolean found = false;
+ Iterator iterator = processes.iterator();
+ while (iterator.hasNext())
+ {
+ ProcessBriefType process = (ProcessBriefType) iterator.next();
+ if (process.getIdentifier().getValue().equalsIgnoreCase(processIdenLocal))
+ {
+ found = true;
+
+ break;
+ }
+ }
+
+ // exit test if my process doesn't exist on server
+ if (!found)
+ {
+ System.out.println("Skipping, gs:AreaGrid not found!");
+ return;
+ }
+
+ // based on the describeprocess, setup the execute
+ ExecuteProcessRequest exeRequest = wps.createExecuteProcessRequest();
+ exeRequest.setIdentifier(processIdenLocal);
+ exeRequest.addInput("envelope", Arrays.asList(wps.createBoundingBoxInputValue("EPSG:4326", 2, Arrays.asList(-180d, -90d), Arrays.asList(180d, 90d))));
+ exeRequest.addInput("width", Arrays.asList(wps.createLiteralInputValue("100")));
+ exeRequest.addInput("height", Arrays.asList(wps.createLiteralInputValue("50")));
+ ResponseDocumentType doc = wps.createResponseDocumentType(false, true, true, "result");
+ DocumentOutputDefinitionType odt = (DocumentOutputDefinitionType) doc.getOutput().get(0);
+ odt.setMimeType("application/arcgrid");
+ odt.setAsReference(true);
+ ResponseFormType responseForm = wps.createResponseForm(doc, null);
+ exeRequest.setResponseForm(responseForm);
+
+ // send the request
+ ExecuteProcessResponse response = wps.issueRequest(exeRequest);
+
+ // response should not be null and no exception should occur.
+ assertNotNull(response);
+
+ // we should get a raw response, no exception, no response document
+ ExecuteResponseType executeResponse = response.getExecuteResponse();
+ assertNotNull(executeResponse);
+
+ // loop and wait for the process to be complete
+ while(executeResponse.getStatus().getProcessFailed() == null
+ && executeResponse.getStatus().getProcessSucceeded() == null) {
+
+ String location = executeResponse.getStatusLocation();
+ URL url = new URL(location);
+ response = wps.issueStatusRequest(url);
+
+ executeResponse = response.getExecuteResponse();
+ assertNotNull(executeResponse);
+ }
+
+ // check result correctness
+ assertEquals(1, executeResponse.getProcessOutputs().getOutput().size());
+ OutputDataType output = (OutputDataType) executeResponse.getProcessOutputs().getOutput().get(0);
+
+ assertEquals("result", output.getIdentifier().getValue());
+ assertEquals("application/arcgrid", output.getReference().getMimeType());
+ assertNotNull(output.getReference().getHref());
+
+ URL dataURL = new URL(output.getReference().getHref());
+ BufferedReader reader = new BufferedReader(new InputStreamReader(dataURL.openStream()));
+ StringBuilder sb = new StringBuilder();
+ String line = null;
+ int count = 0;
+ while((line = reader.readLine()) != null && count <= 5) {
+ sb.append(line).append("\n");
+ count++;
+ }
+ reader.close();
+ String arcgrid = sb.toString();
+ String expectedHeader = "NCOLS 100\n" +
+ "NROWS 50\n" +
+ "XLLCORNER -180.0\n" +
+ "YLLCORNER -90.0\n" +
+ "CELLSIZE 3.6\n" +
+ "NODATA_VALUE -9999";
+ System.out.println(arcgrid);
+ assertTrue(arcgrid.startsWith(expectedHeader));
+ }
}
|
Author: aaime
Date: 2012-03-19 07:36:02 -0700 (Mon, 19 Mar 2012)
New Revision: 38636
Modified:
trunk/modules/unsupported/wps/pom.xml
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractExecuteProcessRequest.java
trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java
trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java
Log:
[GEOT-4083] Add a way to extract the raw response in the WPS client
Modified: trunk/modules/unsupported/wps/pom.xml
===================================================================
--- trunk/modules/unsupported/wps/pom.xml 2012-03-19 09:15:58 UTC (rev 38635)
+++ trunk/modules/unsupported/wps/pom.xml 2012-03-19 14:36:02 UTC (rev 38636)
@@ -124,6 +124,10 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>xpp3</groupId>
+ <artifactId>xpp3_min</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.geotools</groupId>
<artifactId>gt-xml</artifactId>
<version>${project.version}</version>
Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java 2012-03-19 09:15:58 UTC (rev 38635)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/WPS1_0_0.java 2012-03-19 14:36:02 UTC (rev 38636)
@@ -286,7 +286,7 @@
public Response createResponse(HTTPResponse httpResponse) throws ServiceException, IOException
{
- return new ExecuteProcessResponse(httpResponse);
+ return new ExecuteProcessResponse(httpResponse, responseForm != null && responseForm.getRawDataOutput() != null);
}
}
Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractExecuteProcessRequest.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractExecuteProcessRequest.java 2012-03-19 09:15:58 UTC (rev 38635)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/request/AbstractExecuteProcessRequest.java 2012-03-19 14:36:02 UTC (rev 38636)
@@ -65,7 +65,7 @@
*/
private Properties inputs;
- private ResponseFormType responseForm;
+ protected ResponseFormType responseForm;
/**
* Constructs a basic ExecuteProcessRequest, without versioning info.
Modified: trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java
===================================================================
--- trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java 2012-03-19 09:15:58 UTC (rev 38635)
+++ trunk/modules/unsupported/wps/src/main/java/org/geotools/data/wps/response/ExecuteProcessResponse.java 2012-03-19 14:36:02 UTC (rev 38636)
@@ -16,6 +16,7 @@
*/
package org.geotools.data.wps.response;
+import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -31,6 +32,9 @@
import org.geotools.xml.Configuration;
import org.geotools.xml.Parser;
import org.xml.sax.SAXException;
+import org.xmlpull.mxp1.MXParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
/**
@@ -47,6 +51,8 @@
private ExecuteResponseType exeResponse;
private ExceptionReportType excepResponse;
+ private InputStream rawResponseStream;
+ private String rawContentType;
/**
* @param contentType
@@ -54,47 +60,52 @@
* @throws ServiceException
* @throws SAXException
*/
- public ExecuteProcessResponse(HTTPResponse httpResponse) throws IOException, ServiceException
+ public ExecuteProcessResponse(HTTPResponse httpResponse, boolean raw) throws IOException, ServiceException
{
super(httpResponse);
InputStream inputStream = null;
try
{
- inputStream = httpResponse.getResponseStream();
+ if(!raw) {
+ inputStream = httpResponse.getResponseStream();
+ parseDocumentResponse(inputStream);
+ } else {
+ // we need to know if the response was an exception, unfortunately we cannot
+ // make that determination just by looking at the mime type ...
- // Map hints = new HashMap();
- // hints.put(DocumentHandler.DEFAULT_NAMESPACE_HINT_KEY, WPSSchema.getInstance());
- Configuration config = new WPSConfiguration();
- Parser parser = new Parser(config);
+ // could be gml or other stuff, not necessarily a service exception, we need to check if it's an exception or not
+ rawContentType = httpResponse.getContentType();
+ if(rawContentType.startsWith("text/xml")) {
+ // make sure we don't throw away info
+ inputStream = new BufferedInputStream(httpResponse.getResponseStream());
+ inputStream.mark(8192);
+
+ try {
+ XmlPullParser parser = new MXParser();
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+ parser.setInput(inputStream, "UTF-8");
+ parser.nextTag();
+
+ // get the first tag name
+ String name = parser.getName();
+ String namespace = parser.getNamespace();
+ inputStream.reset();
+ if("ServiceException".equals(name) || "ExecuteResponse".equals(name)) {
+ parseDocumentResponse(inputStream);
+ return;
+ }
+ } catch(XmlPullParserException e) {
+ throw new IOException("Failed to parse the response", e);
+ }
+ } else {
+ inputStream = httpResponse.getResponseStream();
+ }
- Object object;
- excepResponse = null;
- exeResponse = null;
- try
- {
- // object = DocumentFactory.getInstance(inputStream, hints, Level.WARNING);
- object = parser.parse(inputStream);
+ // ok, it's really the raw response, store it and avoid closing it
+ rawResponseStream = inputStream;
+ inputStream = null;
}
- catch (SAXException e)
- {
- throw (IOException) new IOException().initCause(e);
- }
- catch (ParserConfigurationException e)
- {
- throw (IOException) new IOException().initCause(e);
- }
-
- // try casting the response
- if (object instanceof ExecuteResponseType)
- {
- exeResponse = (ExecuteResponseType) object;
- }
- // exception caught on server and returned
- else if (object instanceof ExceptionReportType)
- {
- excepResponse = (ExceptionReportType) object;
- }
}
finally
{
@@ -105,6 +116,41 @@
}
}
+ private void parseDocumentResponse(InputStream inputStream) throws IOException {
+ // Map hints = new HashMap();
+ // hints.put(DocumentHandler.DEFAULT_NAMESPACE_HINT_KEY, WPSSchema.getInstance());
+ Configuration config = new WPSConfiguration();
+ Parser parser = new Parser(config);
+
+ Object object;
+ excepResponse = null;
+ exeResponse = null;
+ try
+ {
+ // object = DocumentFactory.getInstance(inputStream, hints, Level.WARNING);
+ object = parser.parse(inputStream);
+ }
+ catch (SAXException e)
+ {
+ throw (IOException) new IOException().initCause(e);
+ }
+ catch (ParserConfigurationException e)
+ {
+ throw (IOException) new IOException().initCause(e);
+ }
+
+ // try casting the response
+ if (object instanceof ExecuteResponseType)
+ {
+ exeResponse = (ExecuteResponseType) object;
+ }
+ // exception caught on server and returned
+ else if (object instanceof ExceptionReportType)
+ {
+ excepResponse = (ExceptionReportType) object;
+ }
+ }
+
public ExecuteResponseType getExecuteResponse()
{
return exeResponse;
@@ -115,4 +161,20 @@
return excepResponse;
}
+ /**
+ * If a raw response was requested, and no service exception has been sent, we should get
+ * the raw response stream here
+ */
+ public InputStream getRawResponseStream() {
+ return rawResponseStream;
+ }
+
+ /**
+ * The raw response stream content type
+ * @return
+ */
+ public String getRawContentType() {
+ return rawContentType;
+ }
+
}
Modified: trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java
===================================================================
--- trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java 2012-03-19 09:15:58 UTC (rev 38635)
+++ trunk/modules/unsupported/wps/src/test/java/org/geotools/data/wps/OnlineWPSManualRequestTest.java 2012-03-19 14:36:02 UTC (rev 38636)
@@ -16,35 +16,27 @@
*/
package org.geotools.data.wps;
+import java.io.BufferedReader;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.LineString;
-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;
-import com.vividsolutions.jts.io.ParseException;
-import com.vividsolutions.jts.io.WKTReader;
-
-import junit.framework.TestCase;
-
import net.opengis.ows11.ExceptionReportType;
import net.opengis.wps10.DataType;
import net.opengis.wps10.ExecuteResponseType;
import net.opengis.wps10.InputDescriptionType;
import net.opengis.wps10.LiteralDataType;
import net.opengis.wps10.OutputDataType;
+import net.opengis.wps10.OutputDefinitionType;
import net.opengis.wps10.ProcessBriefType;
import net.opengis.wps10.ProcessDescriptionType;
import net.opengis.wps10.ProcessDescriptionsType;
import net.opengis.wps10.ProcessOfferingsType;
+import net.opengis.wps10.ResponseFormType;
import net.opengis.wps10.WPSCapabilitiesType;
import org.eclipse.emf.common.util.EList;
@@ -55,7 +47,18 @@
import org.geotools.ows.ServiceException;
import org.geotools.test.OnlineTestCase;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+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;
+import com.vividsolutions.jts.io.ParseException;
+import com.vividsolutions.jts.io.WKTReader;
+
/**
* Test making requests by manually building up requests using the utility methods.
*
@@ -80,6 +83,8 @@
private String processIden;
+ private ResponseFormType response ;
+
/**
* The wps.geoserver fixture consisting of service and processId.
*/
@@ -635,4 +640,179 @@
exeRequest.addInput(idt2.getIdentifier().getValue(), list2);
}
+
+ /**
+ * Try to get an area grid in arcgrid format, raw
+ *
+ * @throws ServiceException
+ * @throws IOException
+ * @throws ParseException
+ */
+ public void testExecuteLocalAreaGrid() throws ServiceException, IOException, ParseException
+ {
+
+ // don't run the test if the server is not up
+ if (fixture == null)
+ {
+ return;
+ }
+
+ if (DISABLE)
+ {
+ return;
+ }
+
+ String processIdenLocal = "gs:AreaGrid";
+
+ WPSCapabilitiesType capabilities = wps.getCapabilities();
+
+ // get the first process and execute it
+ ProcessOfferingsType processOfferings = capabilities.getProcessOfferings();
+ EList processes = processOfferings.getProcess();
+ // ProcessBriefType process = (ProcessBriefType) processes.get(0);
+
+ // does the server contain the specific process I want
+ boolean found = false;
+ Iterator iterator = processes.iterator();
+ while (iterator.hasNext())
+ {
+ ProcessBriefType process = (ProcessBriefType) iterator.next();
+ if (process.getIdentifier().getValue().equalsIgnoreCase(processIdenLocal))
+ {
+ found = true;
+
+ break;
+ }
+ }
+
+ // exit test if my process doesn't exist on server
+ if (!found)
+ {
+ System.out.println("Skipping, gs:AreaGrid not found!");
+ return;
+ }
+
+ // do a full describeprocess on my process
+ DescribeProcessRequest descRequest = wps.createDescribeProcessRequest();
+ descRequest.setIdentifier(processIdenLocal);
+
+ DescribeProcessResponse descResponse = wps.issueRequest(descRequest);
+
+ // based on the describeprocess, setup the execute
+ ProcessDescriptionsType processDesc = descResponse.getProcessDesc();
+ ExecuteProcessRequest exeRequest = wps.createExecuteProcessRequest();
+ exeRequest.setIdentifier(processIdenLocal);
+ exeRequest.addInput("envelope", Arrays.asList(wps.createBoundingBoxInputValue("EPSG:4326", 2, Arrays.asList(-180d, -90d), Arrays.asList(180d, 90d))));
+ exeRequest.addInput("width", Arrays.asList(wps.createLiteralInputValue("2")));
+ exeRequest.addInput("height", Arrays.asList(wps.createLiteralInputValue("1")));
+ OutputDefinitionType rawOutput = wps.createOutputDefinitionType("result");
+ rawOutput.setMimeType("application/arcgrid");
+ ResponseFormType responseForm = wps.createResponseForm(null, rawOutput);
+ exeRequest.setResponseForm(responseForm);
+
+ // send the request
+ ExecuteProcessResponse response = wps.issueRequest(exeRequest);
+
+ // response should not be null and no exception should occur.
+ assertNotNull(response);
+
+ // we should get a raw response, no exception, no response document
+ ExecuteResponseType executeResponse = response.getExecuteResponse();
+ assertNull(executeResponse);
+ ExceptionReportType exceptionResponse = response.getExceptionResponse();
+ assertNull(exceptionResponse);
+
+ // check result correctness
+ assertEquals("application/arcgrid", response.getRawContentType());
+ BufferedReader reader = new BufferedReader(new InputStreamReader(response.getRawResponseStream()));
+ StringBuilder sb = new StringBuilder();
+ String line = null;
+ while((line = reader.readLine()) != null) {
+ sb.append(line).append("\n");
+ }
+ String arcgrid = sb.toString();
+ String expectedHeader = "NCOLS 2\n" +
+ "NROWS 1\n" +
+ "XLLCORNER -180.0\n" +
+ "YLLCORNER -90.0\n" +
+ "CELLSIZE 180.0\n" +
+ "NODATA_VALUE -9999";
+ assertTrue(arcgrid.startsWith(expectedHeader));
+ }
+
+ /**
+ * Request for area grid with raw output but wrong parameters, check the response is an exception
+ *
+ * @throws ServiceException
+ * @throws IOException
+ * @throws ParseException
+ */
+ public void testExecuteLocalAreaGridException() throws ServiceException, IOException, ParseException
+ {
+
+ // don't run the test if the server is not up
+ if (fixture == null)
+ {
+ return;
+ }
+
+ if (DISABLE)
+ {
+ return;
+ }
+
+ String processIdenLocal = "gs:AreaGrid";
+
+ WPSCapabilitiesType capabilities = wps.getCapabilities();
+
+ // get the first process and execute it
+ ProcessOfferingsType processOfferings = capabilities.getProcessOfferings();
+ EList processes = processOfferings.getProcess();
+ // ProcessBriefType process = (ProcessBriefType) processes.get(0);
+
+ // does the server contain the specific process I want
+ boolean found = false;
+ Iterator iterator = processes.iterator();
+ while (iterator.hasNext())
+ {
+ ProcessBriefType process = (ProcessBriefType) iterator.next();
+ if (process.getIdentifier().getValue().equalsIgnoreCase(processIdenLocal))
+ {
+ found = true;
+
+ break;
+ }
+ }
+
+ // exit test if my process doesn't exist on server
+ if (!found)
+ {
+ System.out.println("Skipping, gs:AreaGrid not found!");
+ return;
+ }
+
+ // build the request
+ ExecuteProcessRequest exeRequest = wps.createExecuteProcessRequest();
+ exeRequest.setIdentifier(processIdenLocal);
+ exeRequest.addInput("envelope", Arrays.asList(wps.createBoundingBoxInputValue("EPSG:4326", 2, Arrays.asList(-180d, -90d), Arrays.asList(180d, 90d))));
+ // don't set the width, height required params
+ // exeRequest.addInput("width", Arrays.asList(wps.createLiteralInputValue("abc")));
+ // exeRequest.addInput("height", Arrays.asList(wps.createLiteralInputValue("def")));
+ OutputDefinitionType rawOutput = wps.createOutputDefinitionType("result");
+ rawOutput.setMimeType("application/arcgrid");
+ ResponseFormType responseForm = wps.createResponseForm(null, rawOutput);
+ exeRequest.setResponseForm(responseForm);
+
+ // send the request
+ ExecuteProcessResponse response = wps.issueRequest(exeRequest);
+
+ // response should not be null and no exception should occur.
+ assertNotNull(response);
+
+ // we should get a raw response, no exception, no response document
+ ExecuteResponseType executeResponse = response.getExecuteResponse();
+ assertNotNull(executeResponse);
+ assertNotNull(executeResponse.getStatus().getProcessFailed());
+ assertNotNull( executeResponse.getStatus().getProcessFailed().getExceptionReport());
+ }
}
|
|
From: <svn...@os...> - 2012-03-19 09:16:10
|
Author: bencaradocdavies Date: 2012-03-19 02:15:58 -0700 (Mon, 19 Mar 2012) New Revision: 38635 Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/DataUtilities.java Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADCONGridShiftFactory.java trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactory.java Log: Fix for build failure caused by bad URL to File conversions [GEOT-4080] Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/DataUtilities.java =================================================================== --- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/DataUtilities.java (rev 0) +++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/DataUtilities.java 2012-03-19 09:15:58 UTC (rev 38635) @@ -0,0 +1,80 @@ +/* + * GeoTools - The Open Source Java GIS Toolkit + * http://geotools.org + * + * (C) 2012, 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.referencing.factory.gridshift; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLDecoder; + +/** + * Part of DataUtilities from gt-main, which cannot be used here because of cyclic Maven + * dependencies. + * + * <p> + * + * FIXME: module dependencies should be refactored until this class does not need to exist. + * + * @author Ben Caradoc-Davies (CSIRO Earth Science and Resource Engineering) + */ +public class DataUtilities { + + /** + * Copy of DataUtilities.urlToFile(URL url) in gt-main, which cannot be used here because of + * cyclic Maven dependencies. + */ + public static File urlToFile(URL url) { + if (!"file".equals(url.getProtocol())) { + return null; // not a File URL + } + String string = url.toExternalForm(); + if (string.contains("+")) { + // this represents an invalid URL created using either + // file.toURL(); or + // file.toURI().toURL() on a specific version of Java 5 on Mac + string = string.replace("+", "%2B"); + } + try { + string = URLDecoder.decode(string, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Could not decode the URL to UTF-8 format", e); + } + String path3; + String simplePrefix = "file:/"; + String standardPrefix = "file://"; + String os = System.getProperty("os.name"); + if (os.toUpperCase().contains("WINDOWS") && string.startsWith(standardPrefix)) { + // win32: host/share reference + path3 = string.substring(standardPrefix.length() - 2); + } else if (string.startsWith(standardPrefix)) { + path3 = string.substring(standardPrefix.length()); + } else if (string.startsWith(simplePrefix)) { + path3 = string.substring(simplePrefix.length() - 1); + } else { + String auth = url.getAuthority(); + String path2 = url.getPath().replace("%20", " "); + if (auth != null && !auth.equals("")) { + path3 = "//" + auth + path2; + } else { + path3 = path2; + } + } + return new File(path3); + } + +} Property changes on: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/DataUtilities.java ___________________________________________________________________ Added: svn:mime-type + text/plain Added: svn:keywords + Id URL Added: svn:eol-style + native Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADCONGridShiftFactory.java =================================================================== --- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADCONGridShiftFactory.java 2012-03-17 19:58:42 UTC (rev 38634) +++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADCONGridShiftFactory.java 2012-03-19 09:15:58 UTC (rev 38635) @@ -134,8 +134,8 @@ private NADConGridShift loadGridShiftInternal(URL latGridURL, URL longGridURL) throws FactoryException { // decide if text or binary grid will be used - String latGridName = latGridURL.getFile(); - String longGridName = longGridURL.getFile(); + String latGridName = DataUtilities.urlToFile(latGridURL).getPath(); + String longGridName = DataUtilities.urlToFile(longGridURL).getPath(); try { if ((latGridName.endsWith(".las") && longGridName.endsWith(".los")) || (latGridName.endsWith(".LAS") && longGridName.endsWith(".LOS"))) { @@ -316,7 +316,7 @@ ReadableByteChannel channel = null; if (url.getProtocol().equals("file")) { - File file = new File(url.getFile()); + File file = DataUtilities.urlToFile(url); if (!file.exists() || !file.canRead()) { throw new IOException(Errors.format(ErrorKeys.FILE_DOES_NOT_EXIST_$1, file)); Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactory.java =================================================================== --- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactory.java 2012-03-17 19:58:42 UTC (rev 38634) +++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactory.java 2012-03-19 09:15:58 UTC (rev 38635) @@ -142,7 +142,7 @@ // in memory, but is a quick method to see if file format // is NTv2. if (url.getProtocol().equals("file")) { - File file = new File(url.getFile()); + File file = DataUtilities.urlToFile(url); if (!file.exists() || !file.canRead()) { throw new IOException(Errors.format(ErrorKeys.FILE_DOES_NOT_EXIST_$1, file)); |
Author: aaime
Date: 2012-03-17 12:58:42 -0700 (Sat, 17 Mar 2012)
New Revision: 38634
Added:
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/ClasspathGridShiftLocator.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/GridShiftLocator.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADCONGridShiftFactory.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADConGridShift.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactory.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/NTv2Transform.java
trunk/modules/library/referencing/src/main/resources/META-INF/services/org.geotools.referencing.factory.gridshift.GridShiftLocator
trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/gridshift/
trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactoryTest.java
trunk/modules/library/referencing/src/test/java/org/geotools/referencing/factory/gridshift/TestGridShiftLocator.java
trunk/modules/library/referencing/src/test/java/org/geotools/referencing/operation/transform/NADCONTransformTest.java
trunk/modules/library/referencing/src/test/java/org/geotools/referencing/operation/transform/NTv2TransformTest.java
trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/gridshift/
trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/gridshift/BALR2009.gsb
trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/gridshift/BALR2009_copyright_and_disclaimer.txt
trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/gridshift/malformedNTv2grid.gsb
trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/gridshift/stpaul.las
trunk/modules/library/referencing/src/test/resources/org/geotools/referencing/factory/gridshift/stpaul.los
trunk/modules/plugin/epsg-hsql/src/test/resources/
trunk/modules/plugin/epsg-hsql/src/test/resources/org/
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/gridshift/
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/gridshift/stgeorge.las
trunk/modules/plugin/epsg-hsql/src/test/resources/org/geotools/referencing/factory/gridshift/stgeorge.los
Modified:
trunk/modules/library/referencing/pom.xml
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/ReferencingFactoryFinder.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/MathTransformProvider.java
trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/NADCONTransform.java
trunk/modules/library/referencing/src/main/resources/META-INF/services/org.geotools.referencing.operation.MathTransformProvider
trunk/modules/plugin/epsg-hsql/src/test/java/org/geotools/referencing/CRSTest.java
Log:
[GEOT-4063] NTv2 grid shift transformation (EPSG:9615), patch by Oscar Fonts with improvements for grid lookups and NADCON support by yours truly
Modified: trunk/modules/library/referencing/pom.xml
===================================================================
--- trunk/modules/library/referencing/pom.xml 2012-03-17 14:24:27 UTC (rev 38633)
+++ trunk/modules/library/referencing/pom.xml 2012-03-17 19:58:42 UTC (rev 38634)
@@ -189,6 +189,11 @@
<artifactId>gt-metadata</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>jgridshift</groupId>
+ <artifactId>jgridshift</artifactId>
+ <version>1.0</version>
+ </dependency>
<!-- Test dependencies -->
<dependency>
Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/ReferencingFactoryFinder.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/ReferencingFactoryFinder.java 2012-03-17 14:24:27 UTC (rev 38633)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/ReferencingFactoryFinder.java 2012-03-17 19:58:42 UTC (rev 38634)
@@ -18,37 +18,38 @@
import java.io.IOException;
import java.io.Writer;
-import java.util.Set;
-import java.util.Locale;
import java.util.Collections;
import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Set;
+
import javax.imageio.spi.ServiceRegistry;
+import org.geotools.factory.FactoryCreator;
+import org.geotools.factory.FactoryFinder;
+import org.geotools.factory.FactoryRegistry;
+import org.geotools.factory.FactoryRegistryException;
+import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
+import org.geotools.metadata.iso.citation.Citations;
+import org.geotools.referencing.factory.gridshift.GridShiftLocator;
+import org.geotools.resources.Arguments;
+import org.geotools.resources.LazySet;
import org.opengis.metadata.Identifier;
import org.opengis.metadata.citation.Citation;
+import org.opengis.referencing.AuthorityFactory;
import org.opengis.referencing.Factory;
-import org.opengis.referencing.AuthorityFactory;
+import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CRSFactory;
-import org.opengis.referencing.crs.CRSAuthorityFactory;
+import org.opengis.referencing.cs.CSAuthorityFactory;
import org.opengis.referencing.cs.CSFactory;
-import org.opengis.referencing.cs.CSAuthorityFactory;
+import org.opengis.referencing.datum.DatumAuthorityFactory;
import org.opengis.referencing.datum.DatumFactory;
-import org.opengis.referencing.datum.DatumAuthorityFactory;
+import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
import org.opengis.referencing.operation.CoordinateOperationFactory;
-import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
import org.opengis.referencing.operation.MathTransformFactory;
-import org.geotools.factory.Hints;
-import org.geotools.factory.GeoTools;
-import org.geotools.factory.FactoryFinder;
-import org.geotools.factory.FactoryCreator;
-import org.geotools.factory.FactoryRegistry;
-import org.geotools.factory.FactoryRegistryException;
-import org.geotools.metadata.iso.citation.Citations;
-import org.geotools.resources.Arguments;
-import org.geotools.resources.LazySet;
-
/**
* Defines static methods used to access the application's default {@linkplain Factory
* factory} implementation.
@@ -120,7 +121,8 @@
CRSAuthorityFactory.class,
MathTransformFactory.class,
CoordinateOperationFactory.class,
- CoordinateOperationAuthorityFactory.class});
+ CoordinateOperationAuthorityFactory.class,
+ GridShiftLocator.class});
}
return registry;
}
@@ -486,8 +488,21 @@
{
return getFactories(CoordinateOperationAuthorityFactory.class, hints);
}
-
+
/**
+ * Returns a set of all available implementations for the
+ * {@link GridShiftLocator} interface.
+ *
+ * @param hints An optional map of hints, or {@code null} if none.
+ * @return Set of available grid shift factory implementations.
+ */
+ public static Set<GridShiftLocator> getGridShiftLocators(
+ final Hints hints)
+ {
+ return getFactories(GridShiftLocator.class, hints);
+ }
+
+ /**
* Returns the first implementation of {@link MathTransformFactory} matching the specified
* hints. If no implementation matches, a new one is created if possible or an exception is
* thrown otherwise. If more than one implementation is registered and an
Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/ClasspathGridShiftLocator.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/ClasspathGridShiftLocator.java (rev 0)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/ClasspathGridShiftLocator.java 2012-03-17 19:58:42 UTC (rev 38634)
@@ -0,0 +1,47 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory.gridshift;
+
+import java.net.URL;
+
+import org.geotools.factory.AbstractFactory;
+import org.geotools.metadata.iso.citation.Citations;
+import org.opengis.metadata.citation.Citation;
+
+/**
+ * Default grid shift file locator, looks up grids in the classpath
+ *
+ * @author Andrea Aime - GeoSolutions
+ *
+ */
+public class ClasspathGridShiftLocator extends AbstractFactory implements GridShiftLocator {
+
+ public ClasspathGridShiftLocator() {
+ super(NORMAL_PRIORITY);
+ }
+
+ @Override
+ public Citation getVendor() {
+ return Citations.GEOTOOLS;
+ }
+
+ @Override
+ public URL locateGrid(String grid) {
+ return getClass().getResource(grid);
+ }
+
+}
Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/GridShiftLocator.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/GridShiftLocator.java (rev 0)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/GridShiftLocator.java 2012-03-17 19:58:42 UTC (rev 38634)
@@ -0,0 +1,38 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory.gridshift;
+
+import java.net.URL;
+
+import org.opengis.referencing.Factory;
+
+
+/**
+ * Provides a hook to locate grid shift files, such as NTv1, NTv2 and NADCON ones
+ *
+ * Andrea Aime - Geosolutions
+ */
+public interface GridShiftLocator extends Factory {
+
+ /**
+ * Locate the specified resource.
+ *
+ * @param grid the grid name/location
+ * @return the fully resolved URL of the grid or null, if the resource cannot be located.
+ */
+ URL locateGrid(String grid);
+}
Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADCONGridShiftFactory.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADCONGridShiftFactory.java (rev 0)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADCONGridShiftFactory.java 2012-03-17 19:58:42 UTC (rev 38634)
@@ -0,0 +1,440 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory.gridshift;
+
+import java.io.BufferedReader;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.util.StringTokenizer;
+import java.util.logging.Logger;
+
+import org.geotools.factory.BufferedFactory;
+import org.geotools.referencing.factory.ReferencingFactory;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.SoftValueHashMap;
+import org.geotools.util.logging.Logging;
+import org.opengis.referencing.FactoryException;
+
+/**
+ * Loads and caches NADCON grid shifts
+ *
+ * @author Andrea Aime - GeoSolutions
+ *
+ */
+public class NADCONGridShiftFactory extends ReferencingFactory implements BufferedFactory {
+
+ static final class NADCONKey {
+ String latFile;
+
+ String longFile;
+
+ public NADCONKey(String latFile, String longFile) {
+ super();
+ this.latFile = latFile;
+ this.longFile = longFile;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((latFile == null) ? 0 : latFile.hashCode());
+ result = prime * result + ((longFile == null) ? 0 : longFile.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ NADCONKey other = (NADCONKey) obj;
+ if (latFile == null) {
+ if (other.latFile != null)
+ return false;
+ } else if (!latFile.equals(other.latFile))
+ return false;
+ if (longFile == null) {
+ if (other.longFile != null)
+ return false;
+ } else if (!longFile.equals(other.longFile))
+ return false;
+ return true;
+ }
+
+ }
+
+ /**
+ * The number of hard references to hold internally.
+ */
+ private static final int GRID_CACHE_HARD_REFERENCES = 10;
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOGGER = Logging.getLogger("org.geotools.referencing");
+
+ /**
+ * The soft cache that holds loaded grids.
+ */
+ private SoftValueHashMap<NADCONKey, NADConGridShift> gridCache;
+
+ /**
+ * Constructs a factory with the default priority.
+ */
+ public NADCONGridShiftFactory() {
+ gridCache = new SoftValueHashMap<NADCONKey, NADConGridShift>(GRID_CACHE_HARD_REFERENCES);
+ }
+
+ public NADConGridShift loadGridShift(URL latGridURL, URL longGridURL) throws FactoryException {
+ NADCONKey key = new NADCONKey(latGridURL.toExternalForm(), longGridURL.toExternalForm());
+ synchronized (gridCache) { // Prevent simultaneous threads trying to load same grid
+ NADConGridShift grid = gridCache.get(key);
+ if (grid != null) { // Cached:
+ return grid; // - Return
+ } else { // Not cached:
+ grid = loadGridShiftInternal(latGridURL, longGridURL); // - Load
+ if (grid != null) {
+ gridCache.put(key, grid); // - Cache
+ return grid; // - Return
+ }
+ }
+ throw new FactoryException("NTv2 Grid " + latGridURL + ", " + longGridURL
+ + " could not be created.");
+ }
+ }
+
+ private NADConGridShift loadGridShiftInternal(URL latGridURL, URL longGridURL)
+ throws FactoryException {
+ // decide if text or binary grid will be used
+ String latGridName = latGridURL.getFile();
+ String longGridName = longGridURL.getFile();
+ try {
+ if ((latGridName.endsWith(".las") && longGridName.endsWith(".los"))
+ || (latGridName.endsWith(".LAS") && longGridName.endsWith(".LOS"))) {
+ return loadBinaryGrid(latGridURL, longGridURL);
+ } else if ((latGridName.endsWith(".laa") && longGridName.endsWith(".loa"))
+ || (latGridName.endsWith(".LAA") && longGridName.endsWith(".LOA"))) {
+ return loadTextGrid(latGridURL, longGridURL);
+ } else {
+ throw new FactoryException(Errors.format(ErrorKeys.UNSUPPORTED_FILE_TYPE_$2,
+ latGridName.substring(latGridName.lastIndexOf('.') + 1),
+ longGridName.substring(longGridName.lastIndexOf('.') + 1)));
+ // Note: the +1 above hide the dot, but also make sure that the code is
+ // valid even if the path do not contains '.' at all (-1 + 1 == 0).
+ }
+ } catch (IOException exception) {
+ final Throwable cause = exception.getCause();
+ if (cause instanceof FactoryException) {
+ throw (FactoryException) cause;
+ }
+ throw new FactoryException(exception.getLocalizedMessage(), exception);
+ }
+ }
+
+ /**
+ * Reads latitude and longitude binary grid shift file data into {@link grid}. The file is
+ * organized into records, with the first record containing the header information, followed by
+ * the shift data. The header values are: text describing grid (64 bytes), num. columns (int),
+ * num. rows (int), num. z (int), min x (float), delta x (float), min y (float), delta y (float)
+ * and angle (float). Each record is num. columns 4 bytes + 4 byte separator long and the file
+ * contains num. rows + 1 (for the header) records. The data records (with the grid shift
+ * values) are all floats and have a 4 byte separator (0's) before the data. Row records are
+ * organized from low y (latitude) to high and columns are orderd from low longitude to high.
+ * Everything is written in low byte order.
+ *
+ * @param latGridUrl URL to the binary latitude shift file (.las extention).
+ * @param longGridUrl URL to the binary longitude shift file (.los extention).
+ * @throws IOException if the data files cannot be read.
+ * @throws FactoryException if there is an inconsistency in the data
+ */
+ private NADConGridShift loadBinaryGrid(final URL latGridUrl, final URL longGridUrl)
+ throws IOException, FactoryException {
+ final int HEADER_BYTES = 96;
+ final int SEPARATOR_BYTES = 4;
+ final int DESCRIPTION_LENGTH = 64;
+ ReadableByteChannel latChannel;
+ ReadableByteChannel longChannel;
+ ByteBuffer latBuffer;
+ ByteBuffer longBuffer;
+
+ // //////////////////////
+ // setup
+ // //////////////////////
+ latChannel = getReadChannel(latGridUrl);
+ latBuffer = fillBuffer(latChannel, HEADER_BYTES);
+
+ longChannel = getReadChannel(longGridUrl);
+ longBuffer = fillBuffer(longChannel, HEADER_BYTES);
+
+ // //////////////////////
+ // read header info
+ // //////////////////////
+ // skip the header description
+ latBuffer.position(latBuffer.position() + DESCRIPTION_LENGTH);
+
+ int nc = latBuffer.getInt();
+ int nr = latBuffer.getInt();
+ int nz = latBuffer.getInt();
+
+ float xmin = latBuffer.getFloat();
+ float dx = latBuffer.getFloat();
+ float ymin = latBuffer.getFloat();
+ float dy = latBuffer.getFloat();
+
+ float angle = latBuffer.getFloat();
+ float xmax = xmin + ((nc - 1) * dx);
+ float ymax = ymin + ((nr - 1) * dy);
+
+ // skip the longitude header description
+ longBuffer.position(longBuffer.position() + DESCRIPTION_LENGTH);
+
+ // check that latitude grid header is the same as for latitude grid
+ if ((nc != longBuffer.getInt()) || (nr != longBuffer.getInt())
+ || (nz != longBuffer.getInt()) || (xmin != longBuffer.getFloat())
+ || (dx != longBuffer.getFloat()) || (ymin != longBuffer.getFloat())
+ || (dy != longBuffer.getFloat()) || (angle != longBuffer.getFloat())) {
+ throw new FactoryException(Errors.format(ErrorKeys.GRID_LOCATIONS_UNEQUAL));
+ }
+
+ // //////////////////////
+ // read grid shift data into LocalizationGrid
+ // //////////////////////
+ final int RECORD_LENGTH = (nc * 4) + SEPARATOR_BYTES;
+ final int NUM_BYTES_LEFT = ((nr + 1) * RECORD_LENGTH) - HEADER_BYTES;
+ final int START_OF_DATA = RECORD_LENGTH - HEADER_BYTES;
+
+ latBuffer = fillBuffer(latChannel, NUM_BYTES_LEFT);
+ latBuffer.position(START_OF_DATA); // start of second record (data)
+
+ longBuffer = fillBuffer(longChannel, NUM_BYTES_LEFT);
+ longBuffer.position(START_OF_DATA);
+
+ NADConGridShift gridShift = new NADConGridShift(xmin, ymin, xmax, ymax, dx, dy, nc, nr);
+
+ int i = 0;
+ int j = 0;
+ for (i = 0; i < nr; i++) {
+ latBuffer.position(latBuffer.position() + SEPARATOR_BYTES); // skip record separator
+ longBuffer.position(longBuffer.position() + SEPARATOR_BYTES);
+
+ for (j = 0; j < nc; j++) {
+ gridShift.setLocalizationPoint(j, i, longBuffer.getFloat(), latBuffer.getFloat());
+ }
+ }
+
+ assert i == nr : i;
+ assert j == nc : j;
+
+ return gridShift;
+ }
+
+ /**
+ * Returns a new bytebuffer, of numBytes length and little endian byte order, filled from the
+ * channel.
+ *
+ * @param channel the channel to fill the buffer from
+ * @param numBytes number of bytes to read
+ * @return a new bytebuffer filled from the channel
+ * @throws IOException if there is a problem reading the channel
+ * @throws EOFException if the end of the channel is reached
+ */
+ private ByteBuffer fillBuffer(ReadableByteChannel channel, int numBytes) throws IOException {
+ ByteBuffer buf = ByteBuffer.allocate(numBytes);
+
+ if (fill(buf, channel) == -1) {
+ throw new EOFException(Errors.format(ErrorKeys.END_OF_DATA_FILE));
+ }
+
+ buf.flip();
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+
+ return buf;
+ }
+
+ /**
+ * Fills the bytebuffer from the channel. Code was lifted from ShapefileDataStore.
+ *
+ * @param buffer bytebuffer to fill from the channel
+ * @param channel channel to fill the buffer from
+ * @return number of bytes read
+ * @throws IOException if there is a problem reading the channel
+ */
+ private int fill(ByteBuffer buffer, ReadableByteChannel channel) throws IOException {
+ int r = buffer.remaining();
+
+ // channel reads return -1 when EOF or other error
+ // because they a non-blocking reads, 0 is a valid return value!!
+ while ((buffer.remaining() > 0) && (r != -1)) {
+ r = channel.read(buffer);
+ }
+
+ if (r == -1) {
+ buffer.limit(buffer.position());
+ }
+
+ return r;
+ }
+
+ /**
+ * Obtain a ReadableByteChannel from the given URL. If the url protocol is file, a FileChannel
+ * will be returned. Otherwise a generic channel will be obtained from the urls input stream.
+ * Code swiped from ShapefileDataStore.
+ *
+ * @param url URL to create the channel from
+ * @return a new PeadableByteChannel from the input url
+ * @throws IOException if there is a problem creating the channel
+ */
+ private ReadableByteChannel getReadChannel(URL url) throws IOException {
+ ReadableByteChannel channel = null;
+
+ if (url.getProtocol().equals("file")) {
+ File file = new File(url.getFile());
+
+ if (!file.exists() || !file.canRead()) {
+ throw new IOException(Errors.format(ErrorKeys.FILE_DOES_NOT_EXIST_$1, file));
+ }
+
+ FileInputStream in = new FileInputStream(file);
+ channel = in.getChannel();
+ } else {
+ InputStream in = url.openConnection().getInputStream();
+ channel = Channels.newChannel(in);
+ }
+
+ return channel;
+ }
+
+ /**
+ * Reads latitude and longitude text grid shift file data into {@link grid}. The first two lines
+ * of the shift data file contain the header, with the first being a description of the grid.
+ * The second line contains 8 values separated by spaces: num. columns, num. rows, num. z, min
+ * x, delta x, min y, delta y and angle. Shift data values follow this and are also separated by
+ * spaces. Row records are organized from low y (latitude) to high and columns are orderd from
+ * low longitude to high.
+ *
+ * @param latGridUrl URL to the text latitude shift file (.laa extention).
+ * @param longGridUrl URL to the text longitude shift file (.loa extention).
+ * @throws IOException if the data files cannot be read.
+ * @throws FactoryException if there is an inconsistency in the data
+ */
+ private NADConGridShift loadTextGrid(URL latGridUrl, URL longGridUrl) throws IOException,
+ FactoryException {
+ String latLine;
+ String longLine;
+ StringTokenizer latSt;
+ StringTokenizer longSt;
+
+ // //////////////////////
+ // setup
+ // //////////////////////
+ InputStreamReader latIsr = new InputStreamReader(latGridUrl.openStream());
+ BufferedReader latBr = new BufferedReader(latIsr);
+
+ InputStreamReader longIsr = new InputStreamReader(longGridUrl.openStream());
+ BufferedReader longBr = new BufferedReader(longIsr);
+
+ // //////////////////////
+ // read header info
+ // //////////////////////
+ latLine = latBr.readLine(); // skip header description
+ latLine = latBr.readLine();
+ latSt = new StringTokenizer(latLine, " ");
+
+ if (latSt.countTokens() != 8) {
+ throw new FactoryException(Errors.format(ErrorKeys.HEADER_UNEXPECTED_LENGTH_$1,
+ String.valueOf(latSt.countTokens())));
+ }
+
+ int nc = Integer.parseInt(latSt.nextToken());
+ int nr = Integer.parseInt(latSt.nextToken());
+ int nz = Integer.parseInt(latSt.nextToken());
+
+ float xmin = Float.parseFloat(latSt.nextToken());
+ float dx = Float.parseFloat(latSt.nextToken());
+ float ymin = Float.parseFloat(latSt.nextToken());
+ float dy = Float.parseFloat(latSt.nextToken());
+
+ float angle = Float.parseFloat(latSt.nextToken());
+ float xmax = xmin + ((nc - 1) * dx);
+ float ymax = ymin + ((nr - 1) * dy);
+
+ // now read long shift grid
+ longLine = longBr.readLine(); // skip header description
+ longLine = longBr.readLine();
+ longSt = new StringTokenizer(longLine, " ");
+
+ if (longSt.countTokens() != 8) {
+ throw new FactoryException(Errors.format(ErrorKeys.HEADER_UNEXPECTED_LENGTH_$1,
+ String.valueOf(longSt.countTokens())));
+ }
+
+ // check that latitude grid header is the same as for latitude grid
+ if ((nc != Integer.parseInt(longSt.nextToken()))
+ || (nr != Integer.parseInt(longSt.nextToken()))
+ || (nz != Integer.parseInt(longSt.nextToken()))
+ || (xmin != Float.parseFloat(longSt.nextToken()))
+ || (dx != Float.parseFloat(longSt.nextToken()))
+ || (ymin != Float.parseFloat(longSt.nextToken()))
+ || (dy != Float.parseFloat(longSt.nextToken()))
+ || (angle != Float.parseFloat(longSt.nextToken()))) {
+ throw new FactoryException(Errors.format(ErrorKeys.GRID_LOCATIONS_UNEQUAL));
+ }
+
+ // //////////////////////
+ // read grid shift data into LocalizationGrid
+ // //////////////////////
+ NADConGridShift gridShift = new NADConGridShift(xmin, ymin, xmax, ymax, dx, dy, nc, nr);
+
+ int i = 0;
+ int j = 0;
+ for (i = 0; i < nr; i++) {
+ for (j = 0; j < nc;) {
+ latLine = latBr.readLine();
+ latSt = new StringTokenizer(latLine, " ");
+ longLine = longBr.readLine();
+ longSt = new StringTokenizer(longLine, " ");
+
+ while (latSt.hasMoreTokens() && longSt.hasMoreTokens()) {
+ gridShift.setLocalizationPoint(j, i,
+ (double) Float.parseFloat(longSt.nextToken()),
+ (double) Float.parseFloat(latSt.nextToken()));
+ ++j;
+ }
+ }
+ }
+
+ assert i == nr : i;
+ assert j == nc : j;
+
+ return gridShift;
+ }
+
+}
Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADConGridShift.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADConGridShift.java (rev 0)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NADConGridShift.java 2012-03-17 19:58:42 UTC (rev 38634)
@@ -0,0 +1,157 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory.gridshift;
+
+import org.geotools.referencing.operation.builder.LocalizationGrid;
+
+/**
+ * A NADCON localization grid
+ *
+ * @author Andrea Aime - GeoSolutions
+ * @author Rueben Schulz
+ */
+public class NADConGridShift extends LocalizationGrid {
+
+ /**
+ * The minimum longitude value covered by this grid (decimal degrees)
+ */
+ private double minX;
+
+ /**
+ * The minimum latitude value covered by this grid (decimal degrees)
+ */
+ private double minY;
+
+ /**
+ * The maximum longitude value covered by this grid (decimal degrees)
+ */
+ private double maxX;
+
+ /**
+ * The maximum latitude value covered by this grid (decimal degrees)
+ */
+ private double maxY;
+
+ /**
+ * The difference between longitude grid points (decimal degrees)
+ */
+ private double dx;
+
+ /**
+ * The difference between latitude grid points (decimal degrees)
+ */
+ private double dy;
+
+ public NADConGridShift(double xmin, double ymin, double xmax, double ymax, double dx, double dy, int width, int height) {
+ super(width, height);
+ this.minX = xmin;
+ this.maxX = xmax;
+ this.minY = ymin;
+ this.maxY = ymax;
+ this.dx = dx;
+ this.dy = dy;
+ }
+
+ /**
+ * Returns a hash value for this transform. To make this faster it does not
+ * check the grid values.
+ *
+ * @return a hash value for this transform.
+ */
+ @Override
+ public final int hashCode() {
+ final long code = Double.doubleToLongBits(minX)
+ + (37 * (Double.doubleToLongBits(minY)
+ + (37 * (Double.doubleToLongBits(maxX)
+ + (37 * (Double.doubleToLongBits(maxY)
+ + (37 * (Double.doubleToLongBits(dx)
+ + (37 * (Double.doubleToLongBits(dy)))))))))));
+
+ return (int) code ^ (int) (code >>> 32);
+ }
+
+ /**
+ * Compares the specified object with this math transform for equality.
+ *
+ * @param object the object to compare to
+ * @return {@code true} if the objects are equal.
+ */
+ @Override
+ public final boolean equals(final Object object) {
+ if (object == this) {
+ // Slight optimization
+ return true;
+ }
+
+ if (super.equals(object)) {
+ final NADConGridShift that = (NADConGridShift) object;
+
+ return (Double.doubleToLongBits(this.minX) == Double.doubleToLongBits(that.minX))
+ && (Double.doubleToLongBits(this.minY) == Double.doubleToLongBits(that.minY))
+ && (Double.doubleToLongBits(this.maxX) == Double.doubleToLongBits(that.maxX))
+ && (Double.doubleToLongBits(this.maxY) == Double.doubleToLongBits(that.maxY))
+ && (Double.doubleToLongBits(this.dx) == Double.doubleToLongBits(that.dx))
+ && (Double.doubleToLongBits(this.dy) == Double.doubleToLongBits(that.dy));
+ }
+
+ return false;
+ }
+
+ /**
+ * The minimum longitude value covered by this grid (decimal degrees)
+ */
+ public double getMinX() {
+ return minX;
+ }
+
+ /**
+ * The minimum latitude value covered by this grid (decimal degrees)
+ */
+ public double getMinY() {
+ return minY;
+ }
+
+ /**
+ * The maximum longitude value covered by this grid (decimal degrees)
+ */
+ public double getMaxX() {
+ return maxX;
+ }
+
+ /**
+ * The maximum latitude value covered by this grid (decimal degrees)
+ */
+ public double getMaxY() {
+ return maxY;
+ }
+
+ /**
+ * The difference between longitude grid points (decimal degrees)
+ */
+ public double getDx() {
+ return dx;
+ }
+
+ /**
+ * The difference between latitude grid points (decimal degrees)
+ */
+ public double getDy() {
+ return dy;
+ }
+
+
+}
Added: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactory.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactory.java (rev 0)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/factory/gridshift/NTv2GridShiftFactory.java 2012-03-17 19:58:42 UTC (rev 38634)
@@ -0,0 +1,223 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2012, 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.referencing.factory.gridshift;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.net.URL;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.factory.AbstractFactory;
+import org.geotools.factory.BufferedFactory;
+import org.geotools.referencing.factory.ReferencingFactory;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
+import org.geotools.util.SoftValueHashMap;
+import org.geotools.util.logging.Logging;
+import org.opengis.referencing.FactoryException;
+
+import au.com.objectix.jgridshift.GridShiftFile;
+
+/**
+ * Loads and caches NTv2 grid files. Thisthat incorporates a soft cache mechanism to keep grids in
+ * memory when first loaded. It also checks NTv2 grid file format in {@link #isNTv2Grid(String)}
+ * method.
+ *
+ * @author Oscar Fonts
+ */
+public class NTv2GridShiftFactory extends ReferencingFactory implements BufferedFactory {
+
+ /**
+ * The number of hard references to hold internally.
+ */
+ private static final int GRID_CACHE_HARD_REFERENCES = 10;
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOGGER = Logging.getLogger("org.geotools.referencing");
+
+ /**
+ * The soft cache that holds loaded grids.
+ */
+ private SoftValueHashMap<String, GridShiftFile> ntv2GridCache;
+
+ /**
+ * Constructs a factory with the default priority.
+ */
+ public NTv2GridShiftFactory() {
+ super();
+ ntv2GridCache = new SoftValueHashMap<String, GridShiftFile>(GRID_CACHE_HARD_REFERENCES);
+ }
+
+ /**
+ * Constructs an instance using the specified priority level.
+ *
+ * @param priority The priority for this factory, as a number between
+ * {@link AbstractFactory#MINIMUM_PRIORITY MINIMUM_PRIORITY} and
+ * {@link AbstractFactory#MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
+ */
+ public NTv2GridShiftFactory(final int priority) {
+ super(priority);
+ ntv2GridCache = new SoftValueHashMap<String, GridShiftFile>(GRID_CACHE_HARD_REFERENCES);
+ }
+
+ /**
+ * Performs a NTv2 grid file lookup given its name, and checks for file format correctness.
+ *
+ * @param name The NTv2 grid file name
+ * @return {@code true} if file exists and is valid, {@code false} otherwise
+ */
+ public boolean isNTv2Grid(URL location) {
+ if (location != null) {
+ return isNTv2GridFileValid(location); // Check
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Creates a NTv2 Grid.
+ *
+ * @param name The NTv2 grid name
+ * @return the grid
+ * @throws FactoryException if grid cannot be created
+ */
+ public GridShiftFile createNTv2Grid(URL gridLocation) throws FactoryException {
+ if(gridLocation == null) {
+ throw new FactoryException("The grid location must be not null");
+ }
+
+ synchronized (ntv2GridCache) { // Prevent simultaneous threads trying to load same grid
+ GridShiftFile grid = ntv2GridCache.get(gridLocation.toExternalForm());
+ if (grid != null) { // Cached:
+ return grid; // - Return
+ } else { // Not cached:
+ if (gridLocation != null) {
+ grid = loadNTv2Grid(gridLocation); // - Load
+ if (grid != null) {
+ ntv2GridCache.put(gridLocation.toExternalForm(), grid); // - Cache
+ return grid; // - Return
+ }
+ }
+ throw new FactoryException("NTv2 Grid " + gridLocation + " could not be created.");
+ }
+ }
+ }
+
+
+
+ /**
+ * Checks if a given resource is a valid NTv2 file without fully loading it.
+ *
+ * If file is not valid, the cause is logged at {@link Level#WARNING warning level}.
+ *
+ * @param location the NTv2 file absolute path
+ * @return true if file has NTv2 format, false otherwise
+ */
+ protected boolean isNTv2GridFileValid(URL url) {
+ RandomAccessFile raf = null;
+ InputStream is = null;
+ try {
+
+ // Loading as RandomAccessFile doesn't load the full grid
+ // in memory, but is a quick method to see if file format
+ // is NTv2.
+ if (url.getProtocol().equals("file")) {
+ File file = new File(url.getFile());
+
+ if (!file.exists() || !file.canRead()) {
+ throw new IOException(Errors.format(ErrorKeys.FILE_DOES_NOT_EXIST_$1, file));
+ }
+
+ raf = new RandomAccessFile(file, "r");
+
+ // will throw an exception if not a valid file
+ new GridShiftFile().loadGridShiftFile(raf);
+ } else {
+ InputStream in = url.openConnection().getInputStream();
+
+ // will throw an exception if not a valid file
+ new GridShiftFile().loadGridShiftFile(in, false);
+ }
+
+ return true; // No exception thrown => valid file.
+ } catch (IllegalArgumentException e) {
+ // This usually means resource is not a valid NTv2 file.
+ // Let exception message describe the cause.
+ LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e);
+ return false;
+ } catch (IOException e) {
+ LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e);
+ return false;
+ } finally {
+ try {
+ if (raf != null)
+ raf.close();
+ } catch (IOException e) {
+ }
+
+ try {
+ if (is != null)
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+
+ /**
+ * Loads the grid in memory.
+ *
+ * If file cannot be loaded, the cause is logged at {@link Level#SEVERE severe level}.
+ *
+ * @param location the NTv2 file absolute path
+ * @return the grid, or {@code null} on error
+ * @throws FactoryException
+ */
+ private GridShiftFile loadNTv2Grid(URL location) throws FactoryException {
+ InputStream in = null;
+ try {
+ GridShiftFile grid = new GridShiftFile();
+ in = location.openStream();
+ grid.loadGridShiftFile(in, false); // Load full grid in memory
+ in.close();
+ return grid;
+ } catch (FileNotFoundException e) {
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
+ return null;
+ } catch (IOException e) {
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
+ return null;
+ } catch (IllegalArgumentException e) {
+ LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
+ throw new FactoryException(e.getLocalizedMessage(), e);
+ } finally {
+ try {
+ if (in != null) {
+ in.close();
+ }
+ } catch (IOException e) {
+ // never mind
+ }
+ }
+ }
+
+}
Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/MathTransformProvider.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/MathTransformProvider.java 2012-03-17 14:24:27 UTC (rev 38633)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/MathTransformProvider.java 2012-03-17 19:58:42 UTC (rev 38634)
@@ -238,7 +238,7 @@
* Put the identifiers into a properties map suitable for {@link IdentifiedObject}
* constructor.
*/
- private static Map<String,Object> toMap(final ReferenceIdentifier[] identifiers) {
+ protected static Map<String,Object> toMap(final ReferenceIdentifier[] identifiers) {
ensureNonNull("identifiers", identifiers);
if (identifiers.length == 0) {
throw new IllegalArgumentException(Errors.format(ErrorKeys.EMPTY_ARRAY));
Modified: trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/NADCONTransform.java
===================================================================
--- trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/NADCONTransform.java 2012-03-17 14:24:27 UTC (rev 38633)
+++ trunk/modules/library/referencing/src/main/java/org/geotools/referencing/operation/transform/NADCONTransform.java 2012-03-17 19:58:42 UTC (rev 38634)
@@ -16,49 +16,42 @@
*/
package org.geotools.referencing.operation.transform;
-import java.io.BufferedReader;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.io.Serializable;
+import java.net.URI;
import java.net.URL;
-import java.net.MalformedURLException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.Channels;
-import java.nio.channels.ReadableByteChannel;
-import java.util.StringTokenizer;
import java.util.prefs.Preferences;
-import org.opengis.parameter.GeneralParameterValue;
-import org.opengis.parameter.ParameterDescriptor;
-import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.ParameterNotFoundException;
-import org.opengis.parameter.ParameterValue;
-import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.MathTransform2D;
-import org.opengis.referencing.operation.Transformation;
-import org.opengis.referencing.operation.TransformException;
-
import org.geotools.metadata.iso.citation.Citations;
import org.geotools.parameter.DefaultParameterDescriptor;
import org.geotools.parameter.Parameter;
import org.geotools.parameter.ParameterGroup;
import org.geotools.referencing.NamedIdentifier;
+import org.geotools.referencing.ReferencingFactoryFinder;
+import org.geotools.referencing.factory.gridshift.GridShiftLocator;
+import org.geotools.referencing.factory.gridshift.NADCONGridShiftFactory;
+import org.geotools.referencing.factory.gridshift.NADConGridShift;
import org.geotools.referencing.operation.MathTransformProvider;
import org.geotools.referencing.operation.builder.LocalizationGrid;
import org.geotools.resources.Arguments;
-import org.geotools.resources.i18n.Errors;
import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
import org.geotools.resources.i18n.Vocabulary;
import org.geotools.resources.i18n.VocabularyKeys;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.ParameterDescriptor;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.NoSuchIdentifierException;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.Transformation;
/**
@@ -140,6 +133,11 @@
* Serial number for interoperability with different versions.
*/
private static final long serialVersionUID = -4707304160205218546L;
+
+ /**
+ * The factory that loads the NADCON grids
+ */
+ private static NADCONGridShiftFactory FACTORY = new NADCONGridShiftFactory();
/**
* Preference node for the grid shift file location.
@@ -170,44 +168,15 @@
/**
* Latitude grid shift file names. Output in WKT.
*/
- private final String latGridName;
+ private final URI latGridName;
/**
* Longitude grid shift file names. Output in WKT.
*/
- private final String longGridName;
+ private final URI longGridName;
+
/**
- * The minimum longitude value covered by this grid (decimal degrees)
- */
- private double xmin;
-
- /**
- * The minimum latitude value covered by this grid (decimal degrees)
- */
- private double ymin;
-
- /**
- * The maximum longitude value covered by this grid (decimal degrees)
- */
- private double xmax;
-
- /**
- * The maximum latitude value covered by this grid (decimal degrees)
- */
- private double ymax;
-
- /**
- * The difference between longitude grid points (decimal degrees)
- */
- private double dx;
-
- /**
- * The difference between latitude grid points (decimal degrees)
- */
- private double dy;
-
- /**
* Longitude and latitude grid shift values. Values are organized from low
* to high longitude (low x index to high) and low to high latitude (low y
* index to high).
@@ -226,6 +195,12 @@
private transient MathTransform2D inverse;
/**
+ * The grid driving this transform
+ */
+ NADConGridShift grid;
+
+
+ /**
* Constructs a {@code NADCONTransform} from the specified grid shift files.
*
* @param latGridName path and name (or just name if {@link #GRID_LOCATION}
@@ -240,42 +215,40 @@
* (ie file extentions are unknown or there is an error reading the
* grid files)
*/
- public NADCONTransform(final String latGridName, final String longGridName)
+ public NADCONTransform(final URI latGridName, final URI longGridName)
throws ParameterNotFoundException, FactoryException
{
+ if(latGridName == null) {
+ throw new NoSuchIdentifierException("Latitud grid shift file name is null", null);
+ }
+
+ if(longGridName == null) {
+ throw new NoSuchIdentifierException("Latitud grid shift file name is null", null);
+ }
+
this.latGridName = latGridName;
this.longGridName = longGridName;
-
- //decide if text or binary grid will be used
- try {
- final URL latGridURL = makeURL(latGridName);
- final URL longGridURL = makeURL(longGridName);
-
- if ((latGridName.endsWith(".las") && longGridName.endsWith(".los"))
- || (latGridName.endsWith(".LAS") && longGridName.endsWith(".LOS"))) {
- loadBinaryGrid(latGridURL, longGridURL);
- } else if ((latGridName.endsWith(".laa") && longGridName.endsWith(".loa"))
- || (latGridName.endsWith(".LAA") && longGridName.endsWith(".LOA"))) {
- loadTextGrid(latGridURL, longGridURL);
- } else {
- throw new FactoryException(Errors.format(ErrorKeys.UNSUPPORTED_FILE_TYPE_$2,
- latGridName.substring(latGridName.lastIndexOf('.') + 1),
- longGridName.substring(longGridName.lastIndexOf('.') + 1)));
- // Note: the +1 above hide the dot, but also make sure that the code is
- // valid even if the path do not contains '.' at all (-1 + 1 == 0).
+
+ URL latGridURL = locateGrid(latGridName);
+ URL longGridURL = locateGrid(longGridName);
+
+ this.grid = FACTORY.loadGridShift(latGridURL, longGridURL);
+ this.gridShiftTransform = grid.getMathTransform();
+ }
+
+ URL locateGrid(URI uri ) throws FactoryException {
+ String grid = uri.toString();
+ for (GridShiftLocator locator : ReferencingFactoryFinder.getGridShiftLocators(null)) {
+ URL result = locator.locateGrid(grid);
+ if(result != null) {
+ return result;
}
-
- gridShiftTransform = gridShift.getMathTransform();
- } catch (IOException exception) {
- final Throwable cause = exception.getCause();
- if (cause instanceof FactoryException) {
- throw (FactoryException) cause;
- }
- throw new FactoryException(exception.getLocalizedMessage(),
- exception);
- }
+ };
+
+ throw new FactoryException("Could not locate grid file " + grid);
}
+
/**
* Returns the parameter descriptors for this math transform.
*/
@@ -320,332 +293,6 @@
}
/**
- * Returns a URL from the string representation. If the string has no
- * path, the default path preferece is added.
- *
- * @param str a string representation of a URL
- * @return a URL created from the string representation
- * @throws MalformedURLException if the URL cannot be created
- */
- private URL makeURL(final String str) throws MalformedURLException {
- //has '/' or '\' or ':', so probably full path to file
- if ((str.indexOf('\\') >= 0) || (str.indexOf('/') >= 0) || (str.indexOf(':') >= 0)) {
- return makeURLfromString(str);
- } else {
- // just a file name , prepend base location
- final Preferences prefs = Preferences.userNodeForPackage(NADCONTransform.class);
- final String baseLocation = prefs.get(GRID_LOCATION, DEFAULT_GRID_LOCATION);
- return makeURLfromString(baseLocation + "/" + str);
- }
- }
-
- /**
- * Returns a URL based on a string representation. If no protocol is given,
- * it is assumed to be a local file.
- *
- * @param str a string representation of a URL
- * @return a URL created from the string representation
- * @throws MalformedURLException if the URL cannot be created
- */
- private URL makeURLfromString(final String str) throws MalformedURLException {
- try {
- return new URL(str);
- } catch (MalformedURLException e) {
- //try making this with a file protocal
- return new URL("file", "", str);
- }
- }
-
- /**
- * Reads latitude and longitude binary grid shift file data into {@link
- * grid}. The file is organized into records, with the first record
- * containing the header information, followed by the shift data. The
- * header values are: text describing grid (64 bytes), num. columns (int),
- * num. rows (int), num. z (int), min x (float), delta x (float), min y
- * (float), delta y (float) and angle (float). Each record is num.
- * columns 4 bytes + 4 byte separator long and the file contains num.
- * rows + 1 (for the header) records. The data records (with the grid
- * shift values) are all floats and have a 4 byte separator (0's) before
- * the data. Row records are organized from low y (latitude) to high and
- * columns are orderd from low longitude to high. Everything is written
- * in low byte order.
- *
- * @param latGridUrl URL to the binary latitude shift file (.las extention).
- * @param longGridUrl URL to the binary longitude shift file (.los extention).
- * @throws IOException if the data files cannot be read.
- * @throws FactoryException if there is an inconsistency in the data
- */
- private void loadBinaryGrid(final URL latGridUrl, final URL longGridUrl)
- throws IOException, FactoryException
- {
- final int HEADER_BYTES = 96;
- final int SEPARATOR_BYTES = 4;
- final int DESCRIPTION_LENGTH = 64;
- ReadableByteChannel latChannel;
- ReadableByteChannel longChannel;
- ByteBuffer latBuffer;
- ByteBuffer longBuffer;
-
- ////////////////////////
- //setup
- ////////////////////////
- latChannel = getReadChannel(latGridUrl);
- latBuffer = fillBuffer(latChannel, HEADER_BYTES);
-
- longChannel = getReadChannel(longGridUrl);
- longBuffer = fillBuffer(longChannel, HEADER_BYTES);
-
- ////////////////////////
- //read header info
- ////////////////////////
- //skip the header description
- latBuffer.position(latBuffer.position() + DESCRIPTION_LENGTH);
-
- int nc = latBuffer.getInt();
- int nr = latBuffer.getInt();
- int nz = latBuffer.getInt();
-
- xmin = latBuffer.getFloat();
- dx = latBuffer.getFloat();
- ymin = latBuffer.getFloat();
- dy = latBuffer.getFloat();
-
- float angle = latBuffer.getFloat();
- xmax = xmin + ((nc - 1) * dx);
- ymax = ymin + ((nr - 1) * dy);
-
- //skip the longitude header description
- longBuffer.position(longBuffer.position() + DESCRIPTION_LENGTH);
-
- //check that latitude grid header is the same as for latitude grid
- if ( (nc != longBuffer.getInt())
- || (nr != longBuffer.getInt())
- || (nz != longBuffer.getInt())
- || (xmin != longBuffer.getFloat())
- || (dx != longBuffer.getFloat())
- || (ymin != longBuffer.getFloat())
- || (dy != longBuffer.getFloat())
- || (angle != longBuffer.getFloat())) {
- throw new FactoryException(Errors.format(ErrorKeys.GRID_LOCATIONS_UNEQUAL));
- }
-
- ////////////////////////
- //read grid shift data into LocalizationGrid
- ////////////////////////
- final int RECORD_LENGTH = (nc * 4) + SEPARATOR_BYTES;
- final int NUM_BYTES_LEFT = ((nr + 1) * RECORD_LENGTH) - HEADER_BYTES;
- final int START_OF_DATA = RECORD_LENGTH - HEADER_BYTES;
-
- latBuffer = fillBuffer(latChannel, NUM_BYTES_LEFT);
- latBuffer.position(START_OF_DATA); //start of second record (data)
-
- longBuffer = fillBuffer(longChannel, NUM_BYTES_LEFT);
- longBuffer.position(START_OF_DATA);
-
- gridShift = new LocalizationGrid(nc, nr);
-
- int i = 0;
- int j = 0;
- for (i = 0; i < nr; i++) {
- latBuffer.position(latBuffer.position() + SEPARATOR_BYTES); //skip record separator
- longBuffer.position(longBuffer.position() + SEPARATOR_BYTES);
-
- for (j = 0; j < nc; j++) {
- gridShift.setLocalizationPoint(j, i, longBuffer.getFloat(), latBuffer.getFloat());
- }
- }
-
- assert i == nr : i;
- assert j == nc : j;
- }
-
- /**
- * Returns a new bytebuffer, of numBytes length and little endian byte
- * order, filled from the channel.
- *
- * @param channel the channel to fill the buffer from
- * @param numBytes number of bytes to read
- * @return a new bytebuffer filled from the channel
- * @throws IOException if there is a problem reading the channel
- * @throws EOFException if the end of the channel is reached
- */
- private ByteBuffer fillBuffer(ReadableByteChannel channel, int numBytes)
- throws IOException {
- ByteBuffer buf = ByteBuffer.allocate(numBytes);
-
- if (fill(buf, channel) == -1) {
- throw new EOFException(Errors.format(ErrorKeys.END_OF_DATA_FILE));
- }
-
- buf.flip();
- buf.order(ByteOrder.LITTLE_ENDIAN);
-
- return buf;
- }
-
- /**
- * Fills the bytebuffer from the channel. Code was lifted from
- * ShapefileDataStore.
- *
- * @param buffer bytebuffer to fill from the channel
- * @param channel channel to fill the buffer from
- * @return number of bytes read
- * @throws IOException if there is a problem reading the channel
- */
- private int fill(ByteBuffer buffer, ReadableByt...
[truncated message content] |
|
From: <svn...@os...> - 2012-03-17 14:24:35
|
Author: aaime
Date: 2012-03-17 07:24:27 -0700 (Sat, 17 Mar 2012)
New Revision: 38633
Added:
trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/
trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/AT25_GEOTIFF_1-00.tif
trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.dbf
trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.prj
trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.properties
trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.shp
trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.shx
Modified:
trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerRequest.java
trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/GranuleTest.java
Log:
[GEOT-3704] All coverage formats using RasterLayerRequest break if the destinationToSourceTransform is an affine transform, slight variant of Robert Coup patch
Modified: trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerRequest.java
===================================================================
--- trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerRequest.java 2012-03-17 14:12:26 UTC (rev 38632)
+++ trunk/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerRequest.java 2012-03-17 14:24:27 UTC (rev 38633)
@@ -1140,15 +1140,9 @@
try {
//
- // If this approach succeeds, either the request crs is the same of
- // the coverage crs or the request bbox can be reprojected to that
- // crs
- //
+ // The destination to source transform has been computed (and eventually erased) already
+ // by inspectCoordinateSystem()
-
- // STEP 1: reproject requested BBox to native CRS if needed
- if (!CRS.equalsIgnoreMetadata(requestCRS,rasterManager.spatialDomainManager.coverageCRS2D))
- destinationToSourceTransform = CRS.findMathTransform(requestCRS,rasterManager.spatialDomainManager.coverageCRS2D, true);
// now transform the requested envelope to source crs
if (destinationToSourceTransform != null && !destinationToSourceTransform.isIdentity())
{
@@ -1196,16 +1190,9 @@
// envelope. let's try with wgs84
if(LOGGER.isLoggable(Level.FINE))
LOGGER.log(Level.FINE,te.getLocalizedMessage(),te);
- } catch (FactoryException fe) {
- // something bad happened while trying to transform this
- // envelope. let's try with wgs84
- if(LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE,fe.getLocalizedMessage(),fe);
- }
-
+ }
try {
-
// can we proceed? Do we have geo stuff to do all these operations?
if(rasterManager.spatialDomainManager.coverageGeographicCRS2D!=null&&rasterManager.spatialDomainManager.coverageGeographicBBox!=null){
Modified: trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/GranuleTest.java
===================================================================
--- trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/GranuleTest.java 2012-03-17 14:12:26 UTC (rev 38632)
+++ trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/GranuleTest.java 2012-03-17 14:24:27 UTC (rev 38633)
@@ -31,22 +31,29 @@
import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;
+import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.data.DataUtilities;
import org.geotools.factory.Hints;
+import org.geotools.filter.text.generated.parsers.ParseException;
import org.geotools.gce.imagemosaic.GranuleDescriptor.GranuleOverviewLevelDescriptor;
+import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.geotools.referencing.crs.DefaultProjectedCRS;
import org.geotools.referencing.operation.transform.AffineTransform2D;
+import org.geotools.referencing.wkt.Parser;
import org.geotools.test.TestData;
import org.jaitools.imageutils.ImageLayout2;
import org.junit.Assert;
import org.junit.Test;
+import org.opengis.geometry.BoundingBox;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterValue;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import com.vividsolutions.jts.geom.Geometry;
@@ -188,4 +195,106 @@
assertEquals(translatedRaster.getHeight(), 50);
}
+
+
+ static final String NZTM_WKT_NE = "PROJCS[\"NZGD2000 / New Zealand Transverse Mercator 2000\", \n"
+ + " GEOGCS[\"NZGD2000\", \n"
+ + " DATUM[\"New Zealand Geodetic Datum 2000\", \n"
+ + " SPHEROID[\"GRS 1980\", 6378137.0, 298.257222101, AUTHORITY[\"EPSG\",\"7019\"]], \n"
+ + " TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], \n"
+ + " AUTHORITY[\"EPSG\",\"6167\"]], \n"
+ + " PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n"
+ + " UNIT[\"degree\", 0.017453292519943295], \n"
+ + " AXIS[\"Geodetic latitude\", NORTH], \n"
+ + " AXIS[\"Geodetic longitude\", EAST], \n"
+ + " AUTHORITY[\"EPSG\",\"4167\"]], \n"
+ + " PROJECTION[\"Transverse_Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], \n"
+ + " PARAMETER[\"central_meridian\", 173.0], \n"
+ + " PARAMETER[\"latitude_of_origin\", 0.0], \n"
+ + " PARAMETER[\"scale_factor\", 0.9996], \n"
+ + " PARAMETER[\"false_easting\", 1600000.0], \n"
+ + " PARAMETER[\"false_northing\", 10000000.0], \n"
+ + " UNIT[\"m\", 1.0], \n"
+ + " AXIS[\"Northing\", NORTH], \n"
+ + " AXIS[\"Easting\", EAST], \n"
+ + " AUTHORITY[\"EPSG\",\"2193\"]]";
+
+ static final String NZTM_WKT_EN = "PROJCS[\"NZGD2000 / New Zealand Transverse Mercator 2000\", \n"
+ + " GEOGCS[\"NZGD2000\", \n"
+ + " DATUM[\"New Zealand Geodetic Datum 2000\", \n"
+ + " SPHEROID[\"GRS 1980\", 6378137.0, 298.257222101, AUTHORITY[\"EPSG\",\"7019\"]], \n"
+ + " TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], \n"
+ + " AUTHORITY[\"EPSG\",\"6167\"]], \n"
+ + " PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n"
+ + " UNIT[\"degree\", 0.017453292519943295], \n"
+ + " AXIS[\"Geodetic longitude\", EAST], \n"
+ + " AXIS[\"Geodetic latitude\", NORTH], \n"
+ + " AUTHORITY[\"EPSG\",\"4167\"]], \n"
+ + " PROJECTION[\"Transverse_Mercator\"], \n"
+ + " PARAMETER[\"central_meridian\", 173.0], \n"
+ + " PARAMETER[\"latitude_of_origin\", 0.0], \n"
+ + " PARAMETER[\"scale_factor\", 0.9996], \n"
+ + " PARAMETER[\"false_easting\", 1600000.0], \n"
+ + " PARAMETER[\"false_northing\", 10000000.0], \n"
+ + " UNIT[\"m\", 1.0], \n"
+ + " AXIS[\"Easting\", EAST], \n"
+ + " AXIS[\"Northing\", NORTH], \n"
+ + " AUTHORITY[\"EPSG\",\"2193\"]]";
+
+ @Test
+ public void testCRS_NorthingEasting() throws Exception {
+ // get some test data
+ final File testMosaic = TestData.file(this, "/crs_nztm");
+ assertTrue(testMosaic.exists());
+
+ final Parser parser = new Parser();
+ final DefaultProjectedCRS crs_EN = (DefaultProjectedCRS) parser.parseObject(NZTM_WKT_EN);
+ final DefaultProjectedCRS crs_NE = (DefaultProjectedCRS) parser.parseObject(NZTM_WKT_NE);
+
+ final ImageMosaicReader reader = (ImageMosaicReader) new ImageMosaicFormat()
+ .getReader(testMosaic);
+
+ assertNotNull(reader);
+ final RasterManager manager = new RasterManager(reader);
+
+ // FIXME: somehow when run under JUnit the bounds end up as (y,x) rather than (x,y). Works
+ // fine in GeoServer. Hack it :(
+ final ReferencedEnvelope mosaicBounds = new ReferencedEnvelope(1587997.8835, 1612003.2265,
+ 6162000.4515, 6198002.1165, crs_EN);
+ manager.spatialDomainManager.coverageBBox = mosaicBounds;
+ manager.spatialDomainManager.coverageEnvelope = new GeneralEnvelope(mosaicBounds);
+
+ // set up the request (north-east version)
+ final ReferencedEnvelope requestBBoxNE = new ReferencedEnvelope(6154440.101350001,
+ 6204842.43235, 1583436.86902, 1617044.34782, crs_NE);
+ final ParameterValue<GridGeometry2D> requestedBBox = AbstractGridFormat.READ_GRIDGEOMETRY2D
+ .createValue();
+ requestedBBox.setValue(new GridGeometry2D(PixelInCell.CELL_CENTER, reader
+ .getOriginalGridToWorld(PixelInCell.CELL_CENTER), requestBBoxNE, null));
+
+ final RasterLayerRequest requestNE = new RasterLayerRequest(
+ new GeneralParameterValue[] { requestedBBox }, manager);
+
+ BoundingBox checkCropBBox = requestNE.getCropBBox();
+ assertNotNull(checkCropBBox);
+ assertEquals(
+ "ReferencedEnvelope[1587997.8835 : 1612003.2265, 6162000.4515 : 6198002.1165]",
+ checkCropBBox.toString());
+
+ // set up the request (east-north version)
+ final ReferencedEnvelope requestBBoxEN = new ReferencedEnvelope(1583436.86902,
+ 1617044.34782, 6154440.101350001, 6204842.43235, crs_EN);
+ requestedBBox.setValue(new GridGeometry2D(PixelInCell.CELL_CENTER, reader
+ .getOriginalGridToWorld(PixelInCell.CELL_CENTER), requestBBoxEN, null));
+
+ final RasterLayerRequest requestEN = new RasterLayerRequest(
+ new GeneralParameterValue[] { requestedBBox }, manager);
+
+ checkCropBBox = requestEN.getCropBBox();
+ assertNotNull(checkCropBBox);
+ assertEquals(
+ "ReferencedEnvelope[1587997.8835 : 1612003.2265, 6162000.4515 : 6198002.1165]",
+ checkCropBBox.toString());
+ }
+
}
Added: trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/AT25_GEOTIFF_1-00.tif
===================================================================
--- trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/AT25_GEOTIFF_1-00.tif (rev 0)
+++ trunk/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/AT25_GEOTIFF_1-00.tif 2012-03-17 14:24:27 UTC (rev 38633)
@@ -0,0 +1,3 @@
+II* |
|
From: <svn...@os...> - 2012-03-17 14:12:33
|
Author: aaime
Date: 2012-03-17 07:12:26 -0700 (Sat, 17 Mar 2012)
New Revision: 38632
Added:
branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/
branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/AT25_GEOTIFF_1-00.tif
branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.dbf
branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.prj
branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.properties
branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.shp
branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/mosaic.shx
Modified:
branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerRequest.java
branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/GranuleTest.java
Log:
[GEOT-3704] All coverage formats using RasterLayerRequest break if the destinationToSourceTransform is an affine transform, slight variant of Robert Coup patch
Modified: branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerRequest.java
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerRequest.java 2012-03-16 12:59:08 UTC (rev 38631)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/main/java/org/geotools/gce/imagemosaic/RasterLayerRequest.java 2012-03-17 14:12:26 UTC (rev 38632)
@@ -1140,15 +1140,9 @@
try {
//
- // If this approach succeeds, either the request crs is the same of
- // the coverage crs or the request bbox can be reprojected to that
- // crs
- //
+ // The destination to source transform has been computed (and eventually erased) already
+ // by inspectCoordinateSystem()
-
- // STEP 1: reproject requested BBox to native CRS if needed
- if (!CRS.equalsIgnoreMetadata(requestCRS,rasterManager.spatialDomainManager.coverageCRS2D))
- destinationToSourceTransform = CRS.findMathTransform(requestCRS,rasterManager.spatialDomainManager.coverageCRS2D, true);
// now transform the requested envelope to source crs
if (destinationToSourceTransform != null && !destinationToSourceTransform.isIdentity())
{
@@ -1196,16 +1190,9 @@
// envelope. let's try with wgs84
if(LOGGER.isLoggable(Level.FINE))
LOGGER.log(Level.FINE,te.getLocalizedMessage(),te);
- } catch (FactoryException fe) {
- // something bad happened while trying to transform this
- // envelope. let's try with wgs84
- if(LOGGER.isLoggable(Level.FINE))
- LOGGER.log(Level.FINE,fe.getLocalizedMessage(),fe);
- }
-
+ }
try {
-
// can we proceed? Do we have geo stuff to do all these operations?
if(rasterManager.spatialDomainManager.coverageGeographicCRS2D!=null&&rasterManager.spatialDomainManager.coverageGeographicBBox!=null){
Modified: branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/GranuleTest.java
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/GranuleTest.java 2012-03-16 12:59:08 UTC (rev 38631)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/GranuleTest.java 2012-03-17 14:12:26 UTC (rev 38632)
@@ -31,22 +31,29 @@
import javax.media.jai.ImageLayout;
import javax.media.jai.JAI;
+import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.data.DataUtilities;
import org.geotools.factory.Hints;
+import org.geotools.filter.text.generated.parsers.ParseException;
import org.geotools.gce.imagemosaic.GranuleDescriptor.GranuleOverviewLevelDescriptor;
+import org.geotools.geometry.GeneralEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.image.ImageLayout2;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
+import org.geotools.referencing.crs.DefaultProjectedCRS;
import org.geotools.referencing.operation.transform.AffineTransform2D;
+import org.geotools.referencing.wkt.Parser;
import org.geotools.test.TestData;
import org.junit.Assert;
import org.junit.Test;
+import org.opengis.geometry.BoundingBox;
import org.opengis.parameter.GeneralParameterValue;
import org.opengis.parameter.ParameterValue;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.NoninvertibleTransformException;
import com.vividsolutions.jts.geom.Geometry;
@@ -187,4 +194,106 @@
assertEquals(translatedRaster.getHeight(), 50);
}
+
+
+ static final String NZTM_WKT_NE = "PROJCS[\"NZGD2000 / New Zealand Transverse Mercator 2000\", \n"
+ + " GEOGCS[\"NZGD2000\", \n"
+ + " DATUM[\"New Zealand Geodetic Datum 2000\", \n"
+ + " SPHEROID[\"GRS 1980\", 6378137.0, 298.257222101, AUTHORITY[\"EPSG\",\"7019\"]], \n"
+ + " TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], \n"
+ + " AUTHORITY[\"EPSG\",\"6167\"]], \n"
+ + " PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n"
+ + " UNIT[\"degree\", 0.017453292519943295], \n"
+ + " AXIS[\"Geodetic latitude\", NORTH], \n"
+ + " AXIS[\"Geodetic longitude\", EAST], \n"
+ + " AUTHORITY[\"EPSG\",\"4167\"]], \n"
+ + " PROJECTION[\"Transverse_Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], \n"
+ + " PARAMETER[\"central_meridian\", 173.0], \n"
+ + " PARAMETER[\"latitude_of_origin\", 0.0], \n"
+ + " PARAMETER[\"scale_factor\", 0.9996], \n"
+ + " PARAMETER[\"false_easting\", 1600000.0], \n"
+ + " PARAMETER[\"false_northing\", 10000000.0], \n"
+ + " UNIT[\"m\", 1.0], \n"
+ + " AXIS[\"Northing\", NORTH], \n"
+ + " AXIS[\"Easting\", EAST], \n"
+ + " AUTHORITY[\"EPSG\",\"2193\"]]";
+
+ static final String NZTM_WKT_EN = "PROJCS[\"NZGD2000 / New Zealand Transverse Mercator 2000\", \n"
+ + " GEOGCS[\"NZGD2000\", \n"
+ + " DATUM[\"New Zealand Geodetic Datum 2000\", \n"
+ + " SPHEROID[\"GRS 1980\", 6378137.0, 298.257222101, AUTHORITY[\"EPSG\",\"7019\"]], \n"
+ + " TOWGS84[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], \n"
+ + " AUTHORITY[\"EPSG\",\"6167\"]], \n"
+ + " PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n"
+ + " UNIT[\"degree\", 0.017453292519943295], \n"
+ + " AXIS[\"Geodetic longitude\", EAST], \n"
+ + " AXIS[\"Geodetic latitude\", NORTH], \n"
+ + " AUTHORITY[\"EPSG\",\"4167\"]], \n"
+ + " PROJECTION[\"Transverse_Mercator\"], \n"
+ + " PARAMETER[\"central_meridian\", 173.0], \n"
+ + " PARAMETER[\"latitude_of_origin\", 0.0], \n"
+ + " PARAMETER[\"scale_factor\", 0.9996], \n"
+ + " PARAMETER[\"false_easting\", 1600000.0], \n"
+ + " PARAMETER[\"false_northing\", 10000000.0], \n"
+ + " UNIT[\"m\", 1.0], \n"
+ + " AXIS[\"Easting\", EAST], \n"
+ + " AXIS[\"Northing\", NORTH], \n"
+ + " AUTHORITY[\"EPSG\",\"2193\"]]";
+
+ @Test
+ public void testCRS_NorthingEasting() throws Exception {
+ // get some test data
+ final File testMosaic = TestData.file(this, "/crs_nztm");
+ assertTrue(testMosaic.exists());
+
+ final Parser parser = new Parser();
+ final DefaultProjectedCRS crs_EN = (DefaultProjectedCRS) parser.parseObject(NZTM_WKT_EN);
+ final DefaultProjectedCRS crs_NE = (DefaultProjectedCRS) parser.parseObject(NZTM_WKT_NE);
+
+ final ImageMosaicReader reader = (ImageMosaicReader) new ImageMosaicFormat()
+ .getReader(testMosaic);
+
+ assertNotNull(reader);
+ final RasterManager manager = new RasterManager(reader);
+
+ // FIXME: somehow when run under JUnit the bounds end up as (y,x) rather than (x,y). Works
+ // fine in GeoServer. Hack it :(
+ final ReferencedEnvelope mosaicBounds = new ReferencedEnvelope(1587997.8835, 1612003.2265,
+ 6162000.4515, 6198002.1165, crs_EN);
+ manager.spatialDomainManager.coverageBBox = mosaicBounds;
+ manager.spatialDomainManager.coverageEnvelope = new GeneralEnvelope(mosaicBounds);
+
+ // set up the request (north-east version)
+ final ReferencedEnvelope requestBBoxNE = new ReferencedEnvelope(6154440.101350001,
+ 6204842.43235, 1583436.86902, 1617044.34782, crs_NE);
+ final ParameterValue<GridGeometry2D> requestedBBox = AbstractGridFormat.READ_GRIDGEOMETRY2D
+ .createValue();
+ requestedBBox.setValue(new GridGeometry2D(PixelInCell.CELL_CENTER, reader
+ .getOriginalGridToWorld(PixelInCell.CELL_CENTER), requestBBoxNE, null));
+
+ final RasterLayerRequest requestNE = new RasterLayerRequest(
+ new GeneralParameterValue[] { requestedBBox }, manager);
+
+ BoundingBox checkCropBBox = requestNE.getCropBBox();
+ assertNotNull(checkCropBBox);
+ assertEquals(
+ "ReferencedEnvelope[1587997.8835 : 1612003.2265, 6162000.4515 : 6198002.1165]",
+ checkCropBBox.toString());
+
+ // set up the request (east-north version)
+ final ReferencedEnvelope requestBBoxEN = new ReferencedEnvelope(1583436.86902,
+ 1617044.34782, 6154440.101350001, 6204842.43235, crs_EN);
+ requestedBBox.setValue(new GridGeometry2D(PixelInCell.CELL_CENTER, reader
+ .getOriginalGridToWorld(PixelInCell.CELL_CENTER), requestBBoxEN, null));
+
+ final RasterLayerRequest requestEN = new RasterLayerRequest(
+ new GeneralParameterValue[] { requestedBBox }, manager);
+
+ checkCropBBox = requestEN.getCropBBox();
+ assertNotNull(checkCropBBox);
+ assertEquals(
+ "ReferencedEnvelope[1587997.8835 : 1612003.2265, 6162000.4515 : 6198002.1165]",
+ checkCropBBox.toString());
+ }
+
}
Added: branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/AT25_GEOTIFF_1-00.tif
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/AT25_GEOTIFF_1-00.tif (rev 0)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/test/resources/org/geotools/gce/imagemosaic/test-data/crs_nztm/AT25_GEOTIFF_1-00.tif 2012-03-17 14:12:26 UTC (rev 38632)
@@ -0,0 +1,3 @@
+II* |
|
From: <svn...@os...> - 2012-03-16 12:59:19
|
Author: aaime
Date: 2012-03-16 05:59:08 -0700 (Fri, 16 Mar 2012)
New Revision: 38631
Modified:
branches/2.7.x/modules/library/main/src/main/java/org/geotools/geometry/jts/GeometryCollector.java
branches/2.7.x/modules/library/main/src/test/java/org/geotools/geometry/jts/GeometryCollectorTest.java
Log:
[GEOT-4077] GeometryCollector can build invalid geometries
Modified: branches/2.7.x/modules/library/main/src/main/java/org/geotools/geometry/jts/GeometryCollector.java
===================================================================
--- branches/2.7.x/modules/library/main/src/main/java/org/geotools/geometry/jts/GeometryCollector.java 2012-03-16 12:53:19 UTC (rev 38630)
+++ branches/2.7.x/modules/library/main/src/main/java/org/geotools/geometry/jts/GeometryCollector.java 2012-03-16 12:59:08 UTC (rev 38631)
@@ -143,7 +143,19 @@
return gf.createMultiPoint(array);
} else if (collectionClass == MultiPolygon.class) {
Polygon[] array = (Polygon[]) geometries.toArray(new Polygon[geometries.size()]);
- return gf.createMultiPolygon(array);
+ MultiPolygon mp = gf.createMultiPolygon(array);
+
+ // a collection of valid polygon does not necessarily make up a valid multipolygon
+ if(array.length > 1 && !mp.isValid()) {
+ Geometry g = mp.buffer(0);
+ if(g instanceof Polygon) {
+ return gf.createMultiPolygon(new Polygon[] {(Polygon) g});
+ } else {
+ return (GeometryCollection) g;
+ }
+ } else {
+ return mp;
+ }
} else if (collectionClass == MultiLineString.class) {
LineString[] array = (LineString[]) geometries
.toArray(new LineString[geometries.size()]);
Modified: branches/2.7.x/modules/library/main/src/test/java/org/geotools/geometry/jts/GeometryCollectorTest.java
===================================================================
--- branches/2.7.x/modules/library/main/src/test/java/org/geotools/geometry/jts/GeometryCollectorTest.java 2012-03-16 12:53:19 UTC (rev 38630)
+++ branches/2.7.x/modules/library/main/src/test/java/org/geotools/geometry/jts/GeometryCollectorTest.java 2012-03-16 12:59:08 UTC (rev 38631)
@@ -3,13 +3,13 @@
import static org.junit.Assert.*;
import org.geotools.factory.CommonFactoryFinder;
-import org.geotools.referencing.crs.DefaultGeocentricCRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.junit.Test;
import org.opengis.filter.FilterFactory2;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.WKTReader;
public class GeometryCollectorTest {
@@ -49,7 +49,25 @@
assertSame(p0, result.getGeometryN(0));
assertSame(p1, result.getGeometryN(1));
}
+
+ @Test
+ public void testInvalidMultipolygon() throws Exception {
+ WKTReader reader = new WKTReader();
+ // three triangles that united form a rectangle with a triangular hole in the middle
+ GeometryCollector collector = new GeometryCollector();
+ collector.setFactory(null);
+ final Geometry p0 = reader.read("POLYGON((0 0, 0 3, 3 3, 3 0, 0 0))");
+ collector.add(p0);
+ final Geometry p1 = reader.read("POLYGON((1 1, 1 2, 2 2, 2 1, 1 1))");
+ collector.add(p1);
+
+ GeometryCollection result = collector.collect();
+ assertEquals(1, result.getNumGeometries());
+ Polygon p = (com.vividsolutions.jts.geom.Polygon) result.getGeometryN(0);
+ assertTrue(p.isValid());
+ }
+
@Test
public void testTooMany() throws Exception {
WKTReader reader = new WKTReader();
|
|
From: <svn...@os...> - 2012-03-16 12:53:31
|
Author: aaime
Date: 2012-03-16 05:53:19 -0700 (Fri, 16 Mar 2012)
New Revision: 38630
Modified:
trunk/modules/library/main/src/main/java/org/geotools/geometry/jts/GeometryCollector.java
trunk/modules/library/main/src/test/java/org/geotools/geometry/jts/GeometryCollectorTest.java
Log:
[GEOT-4077] GeometryCollector can build invalid geometries
Modified: trunk/modules/library/main/src/main/java/org/geotools/geometry/jts/GeometryCollector.java
===================================================================
--- trunk/modules/library/main/src/main/java/org/geotools/geometry/jts/GeometryCollector.java 2012-03-13 09:07:21 UTC (rev 38629)
+++ trunk/modules/library/main/src/main/java/org/geotools/geometry/jts/GeometryCollector.java 2012-03-16 12:53:19 UTC (rev 38630)
@@ -144,7 +144,19 @@
return gf.createMultiPoint(array);
} else if (collectionClass == MultiPolygon.class) {
Polygon[] array = (Polygon[]) geometries.toArray(new Polygon[geometries.size()]);
- return gf.createMultiPolygon(array);
+ MultiPolygon mp = gf.createMultiPolygon(array);
+
+ // a collection of valid polygon does not necessarily make up a valid multipolygon
+ if(array.length > 1 && !mp.isValid()) {
+ Geometry g = mp.buffer(0);
+ if(g instanceof Polygon) {
+ return gf.createMultiPolygon(new Polygon[] {(Polygon) g});
+ } else {
+ return (GeometryCollection) g;
+ }
+ } else {
+ return mp;
+ }
} else if (collectionClass == MultiLineString.class) {
LineString[] array = (LineString[]) geometries
.toArray(new LineString[geometries.size()]);
Modified: trunk/modules/library/main/src/test/java/org/geotools/geometry/jts/GeometryCollectorTest.java
===================================================================
--- trunk/modules/library/main/src/test/java/org/geotools/geometry/jts/GeometryCollectorTest.java 2012-03-13 09:07:21 UTC (rev 38629)
+++ trunk/modules/library/main/src/test/java/org/geotools/geometry/jts/GeometryCollectorTest.java 2012-03-16 12:53:19 UTC (rev 38630)
@@ -3,13 +3,13 @@
import static org.junit.Assert.*;
import org.geotools.factory.CommonFactoryFinder;
-import org.geotools.referencing.crs.DefaultGeocentricCRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.junit.Test;
import org.opengis.filter.FilterFactory2;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.Polygon;
import com.vividsolutions.jts.io.WKTReader;
/**
@@ -54,7 +54,25 @@
assertSame(p0, result.getGeometryN(0));
assertSame(p1, result.getGeometryN(1));
}
+
+ @Test
+ public void testInvalidMultipolygon() throws Exception {
+ WKTReader reader = new WKTReader();
+ // three triangles that united form a rectangle with a triangular hole in the middle
+ GeometryCollector collector = new GeometryCollector();
+ collector.setFactory(null);
+ final Geometry p0 = reader.read("POLYGON((0 0, 0 3, 3 3, 3 0, 0 0))");
+ collector.add(p0);
+ final Geometry p1 = reader.read("POLYGON((1 1, 1 2, 2 2, 2 1, 1 1))");
+ collector.add(p1);
+
+ GeometryCollection result = collector.collect();
+ assertEquals(1, result.getNumGeometries());
+ Polygon p = (com.vividsolutions.jts.geom.Polygon) result.getGeometryN(0);
+ assertTrue(p.isValid());
+ }
+
@Test
public void testTooMany() throws Exception {
WKTReader reader = new WKTReader();
|
|
From: <svn...@os...> - 2012-03-13 09:07:32
|
Author: aaime
Date: 2012-03-13 02:07:21 -0700 (Tue, 13 Mar 2012)
New Revision: 38629
Modified:
branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java
Log:
Remove debug statement that breaks the build on Windows
Modified: branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java
===================================================================
--- branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java 2012-03-13 09:03:03 UTC (rev 38628)
+++ branches/2.7.x/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java 2012-03-13 09:07:21 UTC (rev 38629)
@@ -20,6 +20,7 @@
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
+import java.awt.geom.Rectangle2D;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.File;
@@ -36,9 +37,7 @@
import java.util.TimeZone;
import java.util.logging.Logger;
-import javax.imageio.ImageIO;
import javax.media.jai.PlanarImage;
-import javax.media.jai.iterator.RectIterFactory;
import javax.media.jai.widget.ScrollingImagePanel;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@@ -934,7 +933,7 @@
// and that the color is the expected one given the background values provided
RenderedImage ri = coverage.getRenderedImage();
- ImageIO.write(ri, "PNG", new File("/tmp/mix.png"));
+ // ImageIO.write(ri, "PNG", new File("/tmp/mix.png"));
System.out.println(ri.getNumXTiles());
System.out.println(ri.getNumYTiles());
int[] pixel = new int[4];
|
|
From: <svn...@os...> - 2012-03-13 09:03:14
|
Author: aaime
Date: 2012-03-13 02:03:03 -0700 (Tue, 13 Mar 2012)
New Revision: 38628
Modified:
trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java
Log:
Remove debug statement that breaks the build on Windows
Modified: trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java
===================================================================
--- trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java 2012-03-13 06:23:55 UTC (rev 38627)
+++ trunk/modules/plugin/imagemosaic/src/test/java/org/geotools/gce/imagemosaic/ImageMosaicReaderTest.java 2012-03-13 09:03:03 UTC (rev 38628)
@@ -20,7 +20,6 @@
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.io.File;
@@ -37,9 +36,7 @@
import java.util.TimeZone;
import java.util.logging.Logger;
-import javax.imageio.ImageIO;
import javax.media.jai.PlanarImage;
-import javax.media.jai.iterator.RectIterFactory;
import javax.media.jai.widget.ScrollingImagePanel;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
@@ -936,7 +933,7 @@
// and that the color is the expected one given the background values provided
RenderedImage ri = coverage.getRenderedImage();
- ImageIO.write(ri, "PNG", new File("/tmp/mix.png"));
+ // ImageIO.write(ri, "PNG", new File("/tmp/mix.png"));
System.out.println(ri.getNumXTiles());
System.out.println(ri.getNumYTiles());
int[] pixel = new int[4];
|
|
From: <svn...@os...> - 2012-03-13 06:24:03
|
Author: ang05a
Date: 2012-03-12 23:23:55 -0700 (Mon, 12 Mar 2012)
New Revision: 38627
Modified:
trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/FeatureTypeRegistry.java
Log:
GEOT-4035: handle substitutionGroup for basic GML types
Modified: trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/FeatureTypeRegistry.java
===================================================================
--- trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/FeatureTypeRegistry.java 2012-03-11 10:55:17 UTC (rev 38626)
+++ trunk/modules/extension/app-schema/app-schema/src/main/java/org/geotools/data/complex/config/FeatureTypeRegistry.java 2012-03-13 06:23:55 UTC (rev 38627)
@@ -36,6 +36,7 @@
import org.eclipse.xsd.XSDAttributeUseCategory;
import org.eclipse.xsd.XSDComplexTypeDefinition;
import org.eclipse.xsd.XSDElementDeclaration;
+import org.eclipse.xsd.XSDParticle;
import org.eclipse.xsd.XSDTypeDefinition;
import org.geotools.feature.Types;
import org.geotools.feature.type.ComplexFeatureTypeFactoryImpl;
@@ -52,6 +53,7 @@
import org.geotools.xs.XSSchema;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.AttributeType;
+import org.opengis.feature.type.ComplexType;
import org.opengis.feature.type.FeatureTypeFactory;
import org.opengis.feature.type.GeometryType;
import org.opengis.feature.type.Name;
@@ -150,6 +152,24 @@
}
typeRegistry.putAll(FOUNDATION_TYPES);
+
+ // set substitution group for basic types
+ // since the current solution only works for created types (for non basic types)
+ for (AttributeType type : typeRegistry.values()) {
+ if (type instanceof ComplexType) {
+ XSDTypeDefinition typeDef = null;
+ try {
+ typeDef = getTypeDefinition(type.getName());
+ if (typeDef instanceof XSDComplexTypeDefinition) {
+ setSubstitutionGroup((ComplexType) type,
+ (XSDComplexTypeDefinition) typeDef, null, null);
+ }
+ } catch (IllegalArgumentException e) {
+ LOGGER.log(Level.WARNING,
+ "Unable to set substitution group, caused by: " + e.getMessage());
+ }
+ }
+ }
descriptorRegistry.putAll(FOUNDATION_DESCRIPTORS);
}
@@ -200,7 +220,7 @@
}
}
if (elemDecl == null) {
- throw new IllegalArgumentException("No top level element found in schemas: " + qname);
+ throw new NoSuchElementException("No top level element found in schemas: " + qname);
}
return elemDecl;
}
@@ -218,14 +238,61 @@
LOGGER.finest("Creating attribute type " + typeDef.getQName());
type = createType(typeDef, crs, attMappings);
LOGGER.finest("Registering attribute type " + type.getName());
- } else {
- // LOGGER.finer("Ignoring type " +
- // typeDef.getQName()
- // + " as it already exists in the registry");
}
return type;
}
+
+ private void setSubstitutionGroup(ComplexType complexType, XSDComplexTypeDefinition typeDef,
+ CoordinateReferenceSystem crs, List attMappings) {
+ List children = Schemas.getChildElementParticles(typeDef, true);
+ final Collection<PropertyDescriptor> schema = new ArrayList<PropertyDescriptor>(
+ children.size());
+
+ XSDElementDeclaration childDecl;
+ Name typeName;
+ for (Iterator it = children.iterator(); it.hasNext();) {
+ childDecl = (XSDElementDeclaration) ((XSDParticle) it.next()).getContent();
+ if (childDecl.isElementDeclarationReference()) {
+ childDecl = childDecl.getResolvedElementDeclaration();
+ }
+ typeName = Types.typeName(childDecl.getTargetNamespace(), childDecl.getName());
+ try {
+ PropertyDescriptor descriptor = complexType.getDescriptor(typeName);
+ if (descriptor != null) {
+ if (!descriptor.getUserData().containsValue("substitutionGroup")) {
+ List<AttributeDescriptor> substitutionGroup = new ArrayList<AttributeDescriptor>();
+ descriptor.getUserData().put("substitutionGroup", substitutionGroup);
+ Iterator subIt = childDecl.getSubstitutionGroup().iterator();
+ while (subIt.hasNext()) {
+ XSDElementDeclaration sub = (XSDElementDeclaration) subIt.next();
+ if (!sub.getName().equals(childDecl.getName())) {
+ Name elemName = Types.typeName(sub.getTargetNamespace(),
+ sub.getName());
+ XSDTypeDefinition subType = sub.getTypeDefinition();
+ Name name = subType.getName() == null ? elemName : Types.typeName(
+ subType.getTargetNamespace(), subType.getName());
+ AttributeType type = typeRegistry.get(name);
+ if (type != null) {
+ int minOccurs = Schemas.getMinOccurs(typeDef, childDecl);
+ int maxOccurs = Schemas.getMaxOccurs(typeDef, childDecl);
+ boolean nillable = childDecl.isNillable();
+ AttributeDescriptor subDescriptor = createAttributeDescriptor(
+ type, crs, elemName, minOccurs, maxOccurs, nillable,
+ null);
+ substitutionGroup.add(subDescriptor);
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.log(Level.WARNING,
+ "Could not create substitution descriptor: " + e.getMessage());
+ }
+ }
+ }
+
private XSDTypeDefinition getTypeDefinition(Name typeName) {
QName qName = Types.toQName(typeName);
XSDTypeDefinition typeDefinition = null;
@@ -269,6 +336,29 @@
}
+ private AttributeDescriptor createAttributeDescriptor(AttributeType type,
+ CoordinateReferenceSystem crs, Name elemName, int minOccurs, int maxOccurs,
+ boolean nillable, Object defaultValue) {
+ AttributeDescriptor descriptor = null;
+ try {
+ if (!(type instanceof AttributeTypeProxy)
+ && Geometry.class.isAssignableFrom(type.getBinding())) {
+ // create geometry descriptor with the simple feature type CRS
+ GeometryType geomType = new GeometryTypeImpl(type.getName(), type.getBinding(),
+ crs, type.isIdentified(), type.isAbstract(), type.getRestrictions(),
+ type.getSuper(), type.getDescription());
+ descriptor = typeFactory.createGeometryDescriptor(geomType, elemName, minOccurs,
+ maxOccurs, nillable, defaultValue);
+ } else {
+ descriptor = typeFactory.createAttributeDescriptor(type, elemName, minOccurs,
+ maxOccurs, nillable, defaultValue);
+ }
+ } catch (Exception e) {
+ LOGGER.log(Level.WARNING, "Could not create substitution descriptor: " + e.getMessage());
+ }
+ return descriptor;
+ }
+
private AttributeDescriptor createAttributeDescriptor(final XSDComplexTypeDefinition container,
final XSDElementDeclaration elemDecl, int minOccurs, int maxOccurs, CoordinateReferenceSystem crs,
List<AttributeMapping> attMappings, boolean useSubstitutionGroups) {
@@ -294,20 +384,8 @@
maxOccurs = Integer.MAX_VALUE;
}
Object defaultValue = null;
- AttributeDescriptor descriptor;
-
- if (!(type instanceof AttributeTypeProxy)
- && Geometry.class.isAssignableFrom(type.getBinding())) {
- // create geometry descriptor with the simple feature type CRS
- GeometryType geomType = new GeometryTypeImpl(type.getName(), type.getBinding(), crs,
- type.isIdentified(), type.isAbstract(), type.getRestrictions(),
- type.getSuper(), type.getDescription());
- descriptor = typeFactory.createGeometryDescriptor(geomType, elemName, minOccurs,
- maxOccurs, nillable, defaultValue);
- } else {
- descriptor = typeFactory.createAttributeDescriptor(type, elemName, minOccurs,
- maxOccurs, nillable, defaultValue);
- }
+ AttributeDescriptor descriptor = createAttributeDescriptor(type, crs, elemName, minOccurs,
+ maxOccurs, nillable, defaultValue);
descriptor.getUserData().put(XSDElementDeclaration.class, elemDecl);
//NC - substitution groups
|
|
From: <svn...@os...> - 2012-03-11 10:55:24
|
Author: aaime
Date: 2012-03-11 03:55:17 -0700 (Sun, 11 Mar 2012)
New Revision: 38626
Modified:
trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCFeatureStore.java
trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCConnectionLifecycleTest.java
trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCGeographyTest.java
trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCTestSetup.java
trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCUDTTest.java
Log:
[GEOT-4053] JDBCFeatureStore.removeFeatures does not close to the database connection it opened
Modified: trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCFeatureStore.java
===================================================================
--- trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCFeatureStore.java 2012-03-11 10:48:20 UTC (rev 38625)
+++ trunk/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCFeatureStore.java 2012-03-11 10:55:17 UTC (rev 38626)
@@ -350,42 +350,50 @@
super.modifyFeatures(innerTypes, values, filter);
} else {
// let's grab the connection
- Connection cx = getDataStore().getConnection(getState());
+ Connection cx = null;
+ Transaction tx = getState().getTransaction();
+ try {
+ cx = getDataStore().getConnection(tx);
- // we want to support a "batch" update, but we need to be weary of locks
- SimpleFeatureType featureType = getSchema();
- try {
- getDataStore().ensureAuthorization(featureType, preFilter, getTransaction(), cx);
- }
- catch (SQLException e) {
- throw (IOException) new IOException().initCause( e );
- }
- ContentState state = getEntry().getState(transaction);
- ReferencedEnvelope bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
- if( state.hasListener() ){
- // gather bounds before modification
- ReferencedEnvelope before = getBounds( new DefaultQuery( getSchema().getTypeName(), preFilter ) );
- if( before != null && !before.isEmpty() ){
- bounds = before;
+ // we want to support a "batch" update, but we need to be weary of locks
+ SimpleFeatureType featureType = getSchema();
+ try {
+ getDataStore().ensureAuthorization(featureType, preFilter, getTransaction(), cx);
}
- }
- try {
- getDataStore().update(getSchema(), innerTypes, values, preFilter, cx);
- } catch(SQLException e) {
- throw (IOException) (new IOException(e.getMessage()).initCause(e));
- }
-
- if( state.hasListener() ){
- // gather any updated bounds due to a geometry modification
- for( Object value : values ){
- if( value instanceof Geometry ){
- Geometry geometry = (Geometry) value;
- bounds.expandToInclude( geometry.getEnvelopeInternal() );
+ catch (SQLException e) {
+ throw (IOException) new IOException().initCause( e );
+ }
+ ContentState state = getEntry().getState(transaction);
+ ReferencedEnvelope bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
+ if( state.hasListener() ){
+ // gather bounds before modification
+ ReferencedEnvelope before = getBounds( new DefaultQuery( getSchema().getTypeName(), preFilter ) );
+ if( before != null && !before.isEmpty() ){
+ bounds = before;
}
}
- // issue notificaiton
- FeatureEvent event = new FeatureEvent(this, Type.CHANGED, bounds, preFilter );
- state.fireFeatureEvent( event );
+ try {
+ getDataStore().update(getSchema(), innerTypes, values, preFilter, cx);
+ } catch(SQLException e) {
+ throw (IOException) (new IOException(e.getMessage()).initCause(e));
+ }
+
+ if( state.hasListener() ){
+ // gather any updated bounds due to a geometry modification
+ for( Object value : values ){
+ if( value instanceof Geometry ){
+ Geometry geometry = (Geometry) value;
+ bounds.expandToInclude( geometry.getEnvelopeInternal() );
+ }
+ }
+ // issue notificaiton
+ FeatureEvent event = new FeatureEvent(this, Type.CHANGED, bounds, preFilter );
+ state.fireFeatureEvent( event );
+ }
+ } finally {
+ if(tx == null || tx == Transaction.AUTO_COMMIT) {
+ getDataStore().closeSafe(cx);
+ }
}
}
}
@@ -402,30 +410,39 @@
super.removeFeatures(filter);
} else {
// let's grab the connection
- Connection cx = getDataStore().getConnection(getState());
+ Transaction tx = getState().getTransaction();
+ Connection cx = null;
- // we want to support a "batch" delete, but we need to be weary of locks
- SimpleFeatureType featureType = getSchema();
try {
- getDataStore().ensureAuthorization(featureType, preFilter, getTransaction(), cx);
- }
- catch (SQLException e) {
- throw (IOException) new IOException().initCause( e );
- }
- ContentState state = getEntry().getState(transaction);
- ReferencedEnvelope bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
- if( state.hasListener() ){
- // gather bounds before modification
- ReferencedEnvelope before = getBounds( new DefaultQuery( getSchema().getTypeName(), preFilter ) );
- if( before != null && !before.isEmpty() ){
- bounds = before;
+ cx = getDataStore().getConnection(tx);
+
+ // we want to support a "batch" delete, but we need to be weary of locks
+ SimpleFeatureType featureType = getSchema();
+ try {
+ getDataStore().ensureAuthorization(featureType, preFilter, getTransaction(), cx);
+ }
+ catch (SQLException e) {
+ throw (IOException) new IOException().initCause( e );
}
- }
- getDataStore().delete(featureType, preFilter, cx);
- if( state.hasListener() ){
- // issue notification
- FeatureEvent event = new FeatureEvent(this, Type.REMOVED, bounds, preFilter );
- state.fireFeatureEvent( event );
+ ContentState state = getEntry().getState(transaction);
+ ReferencedEnvelope bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
+ if( state.hasListener() ){
+ // gather bounds before modification
+ ReferencedEnvelope before = getBounds( new DefaultQuery( getSchema().getTypeName(), preFilter ) );
+ if( before != null && !before.isEmpty() ){
+ bounds = before;
+ }
+ }
+ getDataStore().delete(featureType, preFilter, cx);
+ if( state.hasListener() ){
+ // issue notification
+ FeatureEvent event = new FeatureEvent(this, Type.REMOVED, bounds, preFilter );
+ state.fireFeatureEvent( event );
+ }
+ } finally {
+ if(tx == null || tx == Transaction.AUTO_COMMIT) {
+ getDataStore().closeSafe(cx);
+ }
}
}
}
Modified: trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCConnectionLifecycleTest.java
===================================================================
--- trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCConnectionLifecycleTest.java 2012-03-11 10:48:20 UTC (rev 38625)
+++ trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCConnectionLifecycleTest.java 2012-03-11 10:55:17 UTC (rev 38626)
@@ -89,6 +89,7 @@
// and now do a rollback
t.rollback();
assertTrue(mockListener.onRollbackCalled);
+ t.close();
}
public void testConnectionReleased() throws IOException {
Modified: trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCGeographyTest.java
===================================================================
--- trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCGeographyTest.java 2012-03-11 10:48:20 UTC (rev 38625)
+++ trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCGeographyTest.java 2012-03-11 10:55:17 UTC (rev 38626)
@@ -172,6 +172,7 @@
f.setDefaultGeometry(point);
fw.write();
+ fw.close();
Filter filter = ff.equals(ff.property("name"), ff.literal("append"));
Query q = new Query(tname("geopoint"), filter);
Modified: trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCTestSetup.java
===================================================================
--- trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCTestSetup.java 2012-03-11 10:48:20 UTC (rev 38625)
+++ trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCTestSetup.java 2012-03-11 10:55:17 UTC (rev 38626)
@@ -16,6 +16,8 @@
*/
package org.geotools.jdbc;
+import static junit.framework.Assert.*;
+
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -98,8 +100,19 @@
}
public void tearDown() throws Exception {
+ final String leakMessage = "Expected no active connection, either there is a connection leak " +
+ "or you forgot to close some object holding onto connections in the tests (e.g., a reader, an iterator)";
if(dataSource instanceof BasicDataSource) {
- ((BasicDataSource) dataSource).close();
+ BasicDataSource bds = (BasicDataSource) dataSource;
+ assertEquals(leakMessage, 0, bds.getNumActive());
+ } else if(dataSource instanceof DBCPDataSource) {
+ BasicDataSource bds = (BasicDataSource) ((DBCPDataSource) dataSource).getWrapped();
+ assertEquals(leakMessage, 0, bds.getNumActive());
+ }
+
+ if(dataSource instanceof BasicDataSource) {
+ BasicDataSource bds = (BasicDataSource) dataSource;
+ bds.close();
} else if(dataSource instanceof ManageableDataSource) {
((ManageableDataSource) dataSource).close();
}
Modified: trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCUDTTest.java
===================================================================
--- trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCUDTTest.java 2012-03-11 10:48:20 UTC (rev 38625)
+++ trunk/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCUDTTest.java 2012-03-11 10:55:17 UTC (rev 38626)
@@ -75,6 +75,7 @@
f.setAttribute(aname("ut"), "34cd");
w.write();
+ w.close();
assertEquals(count+1, dataStore.getFeatureSource(tname("udt")).getCount(Query.ALL));
}
|
|
From: <svn...@os...> - 2012-03-11 10:48:27
|
Author: aaime
Date: 2012-03-11 03:48:20 -0700 (Sun, 11 Mar 2012)
New Revision: 38625
Modified:
branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCFeatureStore.java
branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCConnectionLifecycleTest.java
branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCGeographyTest.java
branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCTestSetup.java
branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCUDTTest.java
Log:
[GEOT-4053] JDBCFeatureStore.removeFeatures does not close to the database connection it opened
Modified: branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCFeatureStore.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCFeatureStore.java 2012-03-09 16:35:53 UTC (rev 38624)
+++ branches/2.7.x/modules/library/jdbc/src/main/java/org/geotools/jdbc/JDBCFeatureStore.java 2012-03-11 10:48:20 UTC (rev 38625)
@@ -335,42 +335,50 @@
super.modifyFeatures(innerTypes, values, filter);
} else {
// let's grab the connection
- Connection cx = getDataStore().getConnection(getState());
+ Connection cx = null;
+ Transaction tx = getState().getTransaction();
+ try {
+ cx = getDataStore().getConnection(tx);
- // we want to support a "batch" update, but we need to be weary of locks
- SimpleFeatureType featureType = getSchema();
- try {
- getDataStore().ensureAuthorization(featureType, preFilter, getTransaction(), cx);
- }
- catch (SQLException e) {
- throw (IOException) new IOException().initCause( e );
- }
- ContentState state = getEntry().getState(transaction);
- ReferencedEnvelope bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
- if( state.hasListener() ){
- // gather bounds before modification
- ReferencedEnvelope before = getBounds( new DefaultQuery( getSchema().getTypeName(), preFilter ) );
- if( before != null && !before.isEmpty() ){
- bounds = before;
+ // we want to support a "batch" update, but we need to be weary of locks
+ SimpleFeatureType featureType = getSchema();
+ try {
+ getDataStore().ensureAuthorization(featureType, preFilter, getTransaction(), cx);
}
- }
- try {
- getDataStore().update(getSchema(), innerTypes, values, preFilter, cx);
- } catch(SQLException e) {
- throw (IOException) (new IOException(e.getMessage()).initCause(e));
- }
-
- if( state.hasListener() ){
- // gather any updated bounds due to a geometry modification
- for( Object value : values ){
- if( value instanceof Geometry ){
- Geometry geometry = (Geometry) value;
- bounds.expandToInclude( geometry.getEnvelopeInternal() );
+ catch (SQLException e) {
+ throw (IOException) new IOException().initCause( e );
+ }
+ ContentState state = getEntry().getState(transaction);
+ ReferencedEnvelope bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
+ if( state.hasListener() ){
+ // gather bounds before modification
+ ReferencedEnvelope before = getBounds( new DefaultQuery( getSchema().getTypeName(), preFilter ) );
+ if( before != null && !before.isEmpty() ){
+ bounds = before;
}
}
- // issue notificaiton
- FeatureEvent event = new FeatureEvent(this, Type.CHANGED, bounds, preFilter );
- state.fireFeatureEvent( event );
+ try {
+ getDataStore().update(getSchema(), innerTypes, values, preFilter, cx);
+ } catch(SQLException e) {
+ throw (IOException) (new IOException(e.getMessage()).initCause(e));
+ }
+
+ if( state.hasListener() ){
+ // gather any updated bounds due to a geometry modification
+ for( Object value : values ){
+ if( value instanceof Geometry ){
+ Geometry geometry = (Geometry) value;
+ bounds.expandToInclude( geometry.getEnvelopeInternal() );
+ }
+ }
+ // issue notificaiton
+ FeatureEvent event = new FeatureEvent(this, Type.CHANGED, bounds, preFilter );
+ state.fireFeatureEvent( event );
+ }
+ } finally {
+ if(tx == null || tx == Transaction.AUTO_COMMIT) {
+ getDataStore().closeSafe(cx);
+ }
}
}
}
@@ -387,30 +395,39 @@
super.removeFeatures(filter);
} else {
// let's grab the connection
- Connection cx = getDataStore().getConnection(getState());
+ Transaction tx = getState().getTransaction();
+ Connection cx = null;
- // we want to support a "batch" delete, but we need to be weary of locks
- SimpleFeatureType featureType = getSchema();
try {
- getDataStore().ensureAuthorization(featureType, preFilter, getTransaction(), cx);
- }
- catch (SQLException e) {
- throw (IOException) new IOException().initCause( e );
- }
- ContentState state = getEntry().getState(transaction);
- ReferencedEnvelope bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
- if( state.hasListener() ){
- // gather bounds before modification
- ReferencedEnvelope before = getBounds( new DefaultQuery( getSchema().getTypeName(), preFilter ) );
- if( before != null && !before.isEmpty() ){
- bounds = before;
+ cx = getDataStore().getConnection(tx);
+
+ // we want to support a "batch" delete, but we need to be weary of locks
+ SimpleFeatureType featureType = getSchema();
+ try {
+ getDataStore().ensureAuthorization(featureType, preFilter, getTransaction(), cx);
+ }
+ catch (SQLException e) {
+ throw (IOException) new IOException().initCause( e );
}
- }
- getDataStore().delete(featureType, preFilter, cx);
- if( state.hasListener() ){
- // issue notification
- FeatureEvent event = new FeatureEvent(this, Type.REMOVED, bounds, preFilter );
- state.fireFeatureEvent( event );
+ ContentState state = getEntry().getState(transaction);
+ ReferencedEnvelope bounds = new ReferencedEnvelope( getSchema().getCoordinateReferenceSystem() );
+ if( state.hasListener() ){
+ // gather bounds before modification
+ ReferencedEnvelope before = getBounds( new DefaultQuery( getSchema().getTypeName(), preFilter ) );
+ if( before != null && !before.isEmpty() ){
+ bounds = before;
+ }
+ }
+ getDataStore().delete(featureType, preFilter, cx);
+ if( state.hasListener() ){
+ // issue notification
+ FeatureEvent event = new FeatureEvent(this, Type.REMOVED, bounds, preFilter );
+ state.fireFeatureEvent( event );
+ }
+ } finally {
+ if(tx == null || tx == Transaction.AUTO_COMMIT) {
+ getDataStore().closeSafe(cx);
+ }
}
}
}
Modified: branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCConnectionLifecycleTest.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCConnectionLifecycleTest.java 2012-03-09 16:35:53 UTC (rev 38624)
+++ branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCConnectionLifecycleTest.java 2012-03-11 10:48:20 UTC (rev 38625)
@@ -89,6 +89,7 @@
// and now do a rollback
t.rollback();
assertTrue(mockListener.onRollbackCalled);
+ t.close();
}
public void testConnectionReleased() throws IOException {
Modified: branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCGeographyTest.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCGeographyTest.java 2012-03-09 16:35:53 UTC (rev 38624)
+++ branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCGeographyTest.java 2012-03-11 10:48:20 UTC (rev 38625)
@@ -167,6 +167,7 @@
f.setDefaultGeometry(point);
fw.write();
+ fw.close();
Filter filter = ff.equals(ff.property("name"), ff.literal("append"));
Query q = new Query(tname("geopoint"), filter);
Modified: branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCTestSetup.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCTestSetup.java 2012-03-09 16:35:53 UTC (rev 38624)
+++ branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCTestSetup.java 2012-03-11 10:48:20 UTC (rev 38625)
@@ -16,6 +16,8 @@
*/
package org.geotools.jdbc;
+import static junit.framework.Assert.*;
+
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -97,8 +99,19 @@
}
public void tearDown() throws Exception {
+ final String leakMessage = "Expected no active connection, either there is a connection leak " +
+ "or you forgot to close some object holding onto connections in the tests (e.g., a reader, an iterator)";
if(dataSource instanceof BasicDataSource) {
- ((BasicDataSource) dataSource).close();
+ BasicDataSource bds = (BasicDataSource) dataSource;
+ assertEquals(leakMessage, 0, bds.getNumActive());
+ } else if(dataSource instanceof DBCPDataSource) {
+ BasicDataSource bds = (BasicDataSource) ((DBCPDataSource) dataSource).getWrapped();
+ assertEquals(leakMessage, 0, bds.getNumActive());
+ }
+
+ if(dataSource instanceof BasicDataSource) {
+ BasicDataSource bds = (BasicDataSource) dataSource;
+ bds.close();
} else if(dataSource instanceof ManageableDataSource) {
((ManageableDataSource) dataSource).close();
}
Modified: branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCUDTTest.java
===================================================================
--- branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCUDTTest.java 2012-03-09 16:35:53 UTC (rev 38624)
+++ branches/2.7.x/modules/library/jdbc/src/test/java/org/geotools/jdbc/JDBCUDTTest.java 2012-03-11 10:48:20 UTC (rev 38625)
@@ -70,6 +70,7 @@
f.setAttribute(aname("ut"), "34cd");
w.write();
+ w.close();
assertEquals(count+1, dataStore.getFeatureSource(tname("udt")).getCount(Query.ALL));
}
|
|
From: <svn...@os...> - 2012-03-09 16:36:03
|
Author: ischneider
Date: 2012-03-09 08:35:53 -0800 (Fri, 09 Mar 2012)
New Revision: 38624
Modified:
trunk/modules/plugin/jdbc/jdbc-teradata/src/main/java/org/geotools/data/teradata/TeradataDataStoreFactory.java
Log:
[GEOT-4068] teradata 'LOB Workaround' parameter poorly named
Modified: trunk/modules/plugin/jdbc/jdbc-teradata/src/main/java/org/geotools/data/teradata/TeradataDataStoreFactory.java
===================================================================
--- trunk/modules/plugin/jdbc/jdbc-teradata/src/main/java/org/geotools/data/teradata/TeradataDataStoreFactory.java 2012-03-09 16:35:47 UTC (rev 38623)
+++ trunk/modules/plugin/jdbc/jdbc-teradata/src/main/java/org/geotools/data/teradata/TeradataDataStoreFactory.java 2012-03-09 16:35:53 UTC (rev 38624)
@@ -50,7 +50,7 @@
*/
public static final Param DBTYPE = new Param("dbtype", String.class, "Type", true, "teradata");
- public static final Param LOBWORKAROUND = new Param("LOB Workaround",Boolean.class,
+ public static final Param LOBWORKAROUND = new Param("Disable LOB Workaround",Boolean.class,
"Disable LOB workaround", false, Boolean.FALSE);
/**
@@ -131,6 +131,12 @@
TeradataDialect dialect = (TeradataDialect) dataStore.getSQLDialect();
Boolean lobWorkaround = (Boolean) LOBWORKAROUND.lookUp(params);
+ // check for old name and respect setting if provided and new name is not
+ // NOTE: this will not appear updated in geoserver's UI however
+ if (lobWorkaround == null && params.containsKey("LOB Workaround")) {
+ lobWorkaround = (Boolean) LOBWORKAROUND.handle((String)params.get("LOB Workaround"));
+ params.put(LOBWORKAROUND.key, lobWorkaround.toString());
+ }
dialect.setLobWorkaroundEnabled(lobWorkaround == null || !lobWorkaround);
Boolean loose = (Boolean) LOOSEBBOX.lookUp(params);
|