Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge remote-tracking branch 'upstream/8.x' into 8.x

  • Loading branch information...
commit 54bdfa9c1fb63914d33b9351aabea02cc9e4c329 2 parents 7ca6cfb + c4cea7d
@gerson721 authored
View
46 modules/library/main/src/main/java/org/geotools/data/collection/CollectionDataStore.java
@@ -21,6 +21,7 @@
import org.geotools.data.AbstractDataStore;
import org.geotools.data.DataSourceException;
+import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureReader;
import org.geotools.data.Query;
import org.geotools.data.SchemaNotFoundException;
@@ -149,24 +150,27 @@ protected ReferencedEnvelope getBounds(Query query) throws SchemaNotFoundExcepti
* @param query
*/
protected ReferencedEnvelope getBoundsInternal(Query query) {
- FeatureIterator<SimpleFeature> iterator = collection.features();
ReferencedEnvelope envelope = new ReferencedEnvelope( featureType.getCoordinateReferenceSystem() );
-
- if (iterator.hasNext()) {
- int count = 1;
- Filter filter = query.getFilter();
-
- while (iterator.hasNext() && (count < query.getMaxFeatures())) {
- SimpleFeature feature = iterator.next();
-
- if (filter.evaluate(feature)) {
- count++;
- envelope.expandToInclude(((Geometry)feature.getDefaultGeometry()).getEnvelopeInternal());
+
+ FeatureIterator<SimpleFeature> iterator = collection.features();
+ try {
+ if (iterator.hasNext()) {
+ int count = 1;
+ Filter filter = query.getFilter();
+
+ while (iterator.hasNext() && (count < query.getMaxFeatures())) {
+ SimpleFeature feature = iterator.next();
+ if (filter.evaluate(feature)) {
+ count++;
+ envelope.expandToInclude(((Geometry)feature.getDefaultGeometry()).getEnvelopeInternal());
+ }
}
}
}
- return envelope;
-
+ finally {
+ iterator.close();
+ }
+ return envelope;
}
/**
@@ -178,18 +182,20 @@ protected int getCount(Query query)
if (!featureType.getTypeName().equals(featureTypeName)) {
throw new SchemaNotFoundException(featureTypeName);
}
- int count = 0;
- FeatureIterator<SimpleFeature> iterator = collection.features();
-
+ int count = 0;
+ FeatureIterator<SimpleFeature> iterator = collection.features();
+ try {
Filter filter = query.getFilter();
-
while (iterator.hasNext() && (count < query.getMaxFeatures())) {
if (filter.evaluate(iterator.next())) {
count++;
}
}
-
- return count;
+ }
+ finally {
+ iterator.close();
+ }
+ return count;
}
/**
View
36 modules/library/main/src/main/java/org/geotools/styling/DefaultResourceLocator.java
@@ -16,9 +16,12 @@
*/
package org.geotools.styling;
+import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
+import org.geotools.data.DataUtilities;
+
/**
* Default locator for online resources. Searches by absolute URL, relative
* path w.r.t. to SLD document or classpath.
@@ -41,15 +44,26 @@ public URL locateResource(String uri) {
URL url = null;
try {
url = new URL(uri);
+
+ //url is valid, check if it is relative
+ File f = DataUtilities.urlToFile(url);
+ if (f != null && !f.isAbsolute()) {
+ //ok, relative url, if the file exists when we are ok
+ if (!f.exists()) {
+ URL relativeUrl = makeRelativeURL(f.getPath());
+ if (relativeUrl != null) {
+ f = DataUtilities.urlToFile(relativeUrl);
+ if (f.exists()) {
+ //bingo!
+ url = relativeUrl;
+ }
+ }
+ }
+ }
} catch (MalformedURLException mfe) {
LOGGER.fine("Looks like " + uri + " is a relative path..");
if (sourceUrl != null) {
- try {
- url = new URL(sourceUrl, uri);
- } catch (MalformedURLException e) {
- LOGGER.warning("can't parse " + uri + " as relative to"
- + sourceUrl.toExternalForm());
- }
+ url = makeRelativeURL(uri);
}
if (url == null)
{
@@ -60,4 +74,14 @@ public URL locateResource(String uri) {
}
return url;
}
+
+ URL makeRelativeURL(String uri) {
+ try {
+ return new URL(sourceUrl, uri);
+ } catch (MalformedURLException e) {
+ LOGGER.warning("can't parse " + uri + " as relative to"
+ + sourceUrl.toExternalForm());
+ }
+ return null;
+ }
}
View
3  modules/library/main/src/main/java/org/geotools/styling/ExternalGraphicImpl.java
@@ -120,6 +120,9 @@ public void setFormat(java.lang.String format) {
* @param location New value of property location.
*/
public void setLocation(java.net.URL location) {
+ if (location == null) {
+ throw new IllegalArgumentException("ExternalGraphic location URL cannot be null");
+ }
this.uri = location.toString();
this.location = location;
}
View
25 modules/library/main/src/test/java/org/geotools/styling/DefaultResourceLocatorTest.java
@@ -0,0 +1,25 @@
+package org.geotools.styling;
+
+import java.io.File;
+import java.net.URL;
+
+import org.geotools.data.DataUtilities;
+
+import junit.framework.TestCase;
+
+public class DefaultResourceLocatorTest extends TestCase {
+
+ public void testRelativeFileURL() throws Exception {
+ DefaultResourceLocator locator = new DefaultResourceLocator();
+ locator.setSourceUrl(getClass().getResource("test-data/blob.gif"));
+
+ checkURL(locator.locateResource("blob.gif"));
+ checkURL(locator.locateResource("file:blob.gif"));
+ }
+
+ void checkURL(URL url) {
+ assertNotNull(url);
+ File f = DataUtilities.urlToFile(url);
+ assertTrue(f.exists());
+ }
+}
View
26 modules/library/metadata/src/main/java/org/geotools/factory/GeoTools.java
@@ -17,6 +17,8 @@
package org.geotools.factory;
import java.awt.RenderingHints;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -79,15 +81,27 @@
*/
private static final Properties PROPS;
static {
+ PROPS = loadProperites("GeoTools.properties");
+ }
+
+ private static Properties loadProperites(String resource) {
Properties props = new Properties();
- try {
- props.load(GeoTools.class.getResourceAsStream("GeoTools.properties"));
+ InputStream stream = GeoTools.class.getResourceAsStream(resource);
+ if (stream != null) {
+ try {
+ props.load(stream);
+ } catch (IOException ignore) {
+ } finally {
+ try {
+ stream.close();
+ } catch (IOException ignore) {
+ }
+ }
}
- catch(Exception e) {}
-
- PROPS = props;
+
+ return props;
}
-
+
/**
* The current GeoTools version. The separator character must be the dot.
*/
View
198 modules/library/render/src/main/java/org/geotools/renderer/lite/RendererUtilities.java
@@ -58,6 +58,9 @@
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.MultiPoint;
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.Polygon;
@@ -531,106 +534,26 @@ public static double calculateScale(ReferencedEnvelope envelope,
throws TransformException, FactoryException {
final double diagonalGroundDistance;
- if (!(envelope.getCoordinateReferenceSystem() instanceof EngineeringCRS)) { // geographic or cad?
- // //
- //
- // get CRS2D for this referenced envelope, check that its 2d
- //
- // //
- final CoordinateReferenceSystem tempCRS = CRS.getHorizontalCRS(envelope.getCoordinateReferenceSystem());
- if(tempCRS==null)
- throw new TransformException(Errors.format(
- ErrorKeys.CANT_REDUCE_TO_TWO_DIMENSIONS_$1,
- envelope.getCoordinateReferenceSystem()));
- // make sure the crs is 2d
- envelope = new ReferencedEnvelope((Envelope) envelope, tempCRS);
- final MathTransform toWGS84 = CRS.findMathTransform(tempCRS, DefaultGeographicCRS.WGS84, true);
-
- // //
- // Try to compute the source crs envelope, either by asking CRS or
- // by trying to project the WGS84 envelope (world) to the specified
- // CRS
- // //
- GeneralEnvelope sourceCRSEnvelope = (GeneralEnvelope) CRS
- .getEnvelope(tempCRS);
- if (sourceCRSEnvelope == null) {
- try {
- // try to compute the envelope by reprojecting the WGS84
- // envelope
- sourceCRSEnvelope = CRS.transform(toWGS84
- .inverse(), CRS.getEnvelope(DefaultGeographicCRS.WGS84));
- } catch (TransformException e) {
- // for some transformations this is normal, it's not possible
- // to project the whole WGS84 envelope in many transforms,
- // such as Mercator or Gauss (the transform does diverge)
- }catch ( AssertionError ae){
- // same reason as above basically. For some
- // projections the assertion will complain. Nothing can be done about this
- }
- }
-
- // //
- //
- // Make sure it intersect the world in the source projection by
- // intersecting the provided envelope with the envelope of its crs.
- //
- // This will also prevent us from having problems with requests for
- // images bigger than the world (thanks Dave!!!)
- //
- // It is important to note that I also have to update the image
- // width in case the provided envelope is bigger than the envelope of the
- // source crs.
- // //
- final GeneralEnvelope intersectedEnvelope = new GeneralEnvelope(
- envelope);
- if (sourceCRSEnvelope != null) {
- intersectedEnvelope.intersect(sourceCRSEnvelope);
- if (intersectedEnvelope.isEmpty())
- throw new IllegalArgumentException(
- "The provided envelope is outside the source CRS definition area");
- if (!intersectedEnvelope.equals(envelope)) {
- final double scale0 = intersectedEnvelope.getSpan(0)
- / envelope.getSpan(0);
- final double scale1 = intersectedEnvelope.getSpan(1)
- / envelope.getSpan(1);
- imageWidth *= scale0;
- imageHeight *= scale1;
- }
- }
-
- // //
- //
- // Go to WGS84 in order to see how things are there
- //
- // //
- final GeneralEnvelope geographicEnvelope = CRS.transform(
- toWGS84, intersectedEnvelope);
- geographicEnvelope.setCoordinateReferenceSystem(DefaultGeographicCRS.WGS84);
-
- // //
- //
- // Instantiate a geodetic calculator for GCS WGS84 and get the
- // orthodromic distance between LLC and UC of the geographic
- // envelope.
- //
- // //
- final GeodeticCalculator calculator = new GeodeticCalculator(
- DefaultGeographicCRS.WGS84);
- final DirectPosition lowerLeftCorner = geographicEnvelope
- .getLowerCorner();
- final DirectPosition upperRightCorner = geographicEnvelope
- .getUpperCorner();
- calculator.setStartingGeographicPoint(lowerLeftCorner
- .getOrdinate(0), lowerLeftCorner.getOrdinate(1));
- calculator.setDestinationGeographicPoint(upperRightCorner
- .getOrdinate(0), upperRightCorner.getOrdinate(1));
- diagonalGroundDistance = calculator
- .getOrthodromicDistance();
- } else {
- // if it's an engineering crs, compute only the graphical scale, assuming a CAD space
- diagonalGroundDistance = Math.sqrt(envelope.getWidth() * envelope.getWidth()
- + envelope.getHeight() * envelope.getHeight());
- }
+ if (!(envelope.getCoordinateReferenceSystem() instanceof EngineeringCRS)) {
+ // //
+ //
+ // get CRS2D for this referenced envelope, check that its 2d
+ //
+ // //
+ final CoordinateReferenceSystem tempCRS = CRS.getHorizontalCRS(envelope
+ .getCoordinateReferenceSystem());
+ if (tempCRS == null) {
+ throw new TransformException(Errors.format(
+ ErrorKeys.CANT_REDUCE_TO_TWO_DIMENSIONS_$1,
+ envelope.getCoordinateReferenceSystem()));
+ }
+ ReferencedEnvelope envelopeWGS84 = envelope.transform(DefaultGeographicCRS.WGS84, true);
+ diagonalGroundDistance = geodeticDiagonalDistance(envelopeWGS84);
+ } else {
+ // if it's an engineering crs, compute only the graphical scale, assuming a CAD space
+ diagonalGroundDistance = Math.sqrt(envelope.getWidth() * envelope.getWidth()
+ + envelope.getHeight() * envelope.getHeight());
+ }
// //
//
@@ -646,6 +569,81 @@ public static double calculateScale(ReferencedEnvelope envelope,
// remember, this is the denominator, not the actual scale;
}
+ private static double geodeticDiagonalDistance(Envelope env) {
+ if(env.getWidth() < 180 && env.getHeight() < 180) {
+ return getGeodeticSegmentLength(env.getMinX(), env.getMinY(), env.getMaxX(), env.getMaxY());
+ } else {
+ // we cannot compute geodetic distance for distances longer than a hemisphere,
+ // we have to build a set of lines connecting the two points that are smaller to
+ // get a value that makes any sense rendering wise by crossing the original line with
+ // a set of quadrants that are 180x180
+ double distance = 0;
+ GeometryFactory gf = new GeometryFactory();
+ LineString ls = gf.createLineString(new Coordinate[] {new Coordinate(env.getMinX(), env.getMinY()),
+ new Coordinate(env.getMaxX(), env.getMaxY())});
+ int qMinX = (int) (Math.signum(env.getMinX()) * Math.ceil(Math.abs(env.getMinX() / 180.0)));
+ int qMaxX = (int) (Math.signum(env.getMaxX()) * Math.ceil(Math.abs(env.getMaxX() / 180.0)));
+ int qMinY = (int) (Math.signum(env.getMinY()) * Math.ceil(Math.abs((env.getMinY() + 90) / 180.0)));
+ int qMaxY = (int) (Math.signum(env.getMaxY()) * Math.ceil(Math.abs((env.getMaxY() + 90) / 180.0)));
+ for (int i = qMinX; i < qMaxX; i++) {
+ for (int j = qMinY; j < qMaxY; j++) {
+ double minX = i * 180.0;
+ double minY = j * 180.0 - 90;
+ double maxX = minX + 180;
+ double maxY = minY + 180;
+ LinearRing ring = gf.createLinearRing(new Coordinate[] {new Coordinate(minX, minY),
+ new Coordinate(minX, maxY), new Coordinate(maxX, maxY), new Coordinate(maxX, minY),
+ new Coordinate(minX, minY)});
+ Polygon p = gf.createPolygon(ring, null);
+ Geometry intersection = p.intersection(ls);
+ if(intersection instanceof LineString) {
+ LineString ils = ((LineString) intersection);
+ double d = getGeodeticSegmentLength(ils);
+ distance += d;
+ } else if(intersection instanceof GeometryCollection) {
+ GeometryCollection igc = ((GeometryCollection) intersection);
+ for (int k = 0; k < igc.getNumGeometries(); k++) {
+ Geometry child = igc.getGeometryN(k);
+ if(child instanceof LineString) {
+ double d = getGeodeticSegmentLength((LineString) child);
+ distance += d;
+ }
+ }
+ }
+ }
+ }
+
+ return distance;
+ }
+ }
+
+ private static double getGeodeticSegmentLength(LineString ls) {
+ Coordinate start = ls.getCoordinateN(0);
+ Coordinate end = ls.getCoordinateN(1);
+ return getGeodeticSegmentLength(start.x, start.y, end.x, end.y);
+ }
+
+ private static double getGeodeticSegmentLength(double minx, double miny, double maxx, double maxy) {
+ final GeodeticCalculator calculator = new GeodeticCalculator(DefaultGeographicCRS.WGS84);
+ double rminx = rollLongitude(minx);
+ double rminy = rollLatitude(miny);
+ double rmaxx = rollLongitude(maxx);
+ double rmaxy = rollLatitude(maxy);
+ calculator.setStartingGeographicPoint(rminx, rminy);
+ calculator.setDestinationGeographicPoint(rmaxx, rmaxy);
+ return calculator.getOrthodromicDistance();
+ }
+
+ protected static double rollLongitude(final double x) {
+ double rolled = x - (((int) (x + Math.signum(x) * 180)) / 360) * 360.0;
+ return rolled;
+ }
+
+ protected static double rollLatitude(final double x) {
+ double rolled = x - (((int) (x + Math.signum(x) * 90)) / 180) * 180.0;
+ return rolled;
+ }
+
/**
* This worldToScreenTransform method makes the assumption that the crs is
View
8 modules/library/render/src/test/java/org/geotools/renderer/lite/LabelObstacleTest.java
@@ -16,9 +16,8 @@
*/
package org.geotools.renderer.lite;
-import static java.awt.RenderingHints.KEY_ANTIALIASING;
-import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON;
-import static org.junit.Assert.assertEquals;
+import static java.awt.RenderingHints.*;
+import static org.junit.Assert.*;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
@@ -43,6 +42,7 @@
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.image.test.ImageAssert;
import org.geotools.map.DefaultMapContext;
+import org.geotools.referencing.CRS;
import org.geotools.styling.SLDParser;
import org.geotools.styling.Style;
import org.junit.BeforeClass;
@@ -73,7 +73,7 @@ public static void setUpData() throws Exception {
SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
tb.setName("roads");
- tb.setSRS("epsg:4326");
+ tb.setCRS(CRS.decode("EPSG:4326", true));
tb.add("geom", LineString.class);
tb.add("name", String.class);
mem.createSchema(tb.buildFeatureType());
View
49 modules/library/render/src/test/java/org/geotools/renderer/lite/RenderUtilitiesTest.java
@@ -38,17 +38,44 @@
*/
public class RenderUtilitiesTest extends TestCase {
- public void testScaleOutsideCrsDefinition() throws Exception {
- CoordinateReferenceSystem utm1N = CRS.decode("EPSG:32601");
- ReferencedEnvelope re = new ReferencedEnvelope(new Envelope(0, 0, 100,
- 100), utm1N);
- try {
- RendererUtilities.calculateScale(re, 100, 100, 75);
- fail("Should have failed, envelope outside of the source crs validity area");
- } catch (IllegalArgumentException e) {
- // ok
- }
- }
+ /**
+ * This tests a fix to handle Geographic CRSes (such as NAD83)
+ * whose domain of validity crosses the Date Line.
+ * Previously this would cause a failure.
+ *
+ * @throws Exception
+ */
+ public void testNAD83() throws Exception {
+ CoordinateReferenceSystem nad83 = CRS.decode("EPSG:4269", true);
+ ReferencedEnvelope re = new ReferencedEnvelope(
+ new Envelope(-121.1, -121.0, 46.7, 46.8), nad83);
+ double scale = RendererUtilities.calculateScale(re, 750, 600, 75);
+ assertEquals(41470, scale, 1d);
+ }
+
+ public void testWGS84() throws Exception {
+ CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326", true);
+ ReferencedEnvelope re = new ReferencedEnvelope(
+ new Envelope(-121.1, -121.0, 46.7, 46.8), wgs84);
+ double scale = RendererUtilities.calculateScale(re, 750, 600, 75);
+ assertEquals(41470, scale, 1d);
+ }
+
+ public void testWorld() throws Exception {
+ CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326", true);
+ ReferencedEnvelope re = new ReferencedEnvelope(
+ new Envelope(-180, 180, -90, 90), wgs84);
+ double scale = RendererUtilities.calculateScale(re, 1000, 500, 75);
+ assertEquals(52830886, scale, 1);
+ }
+
+ public void testWorldTwice() throws Exception {
+ CoordinateReferenceSystem wgs84 = CRS.decode("EPSG:4326", true);
+ ReferencedEnvelope re = new ReferencedEnvelope(
+ new Envelope(-360, 360, -180, 180), wgs84);
+ double scale = RendererUtilities.calculateScale(re, 1000, 500, 75);
+ assertEquals(52830886 * 2, scale, 1);
+ }
public void testScaleProjected() throws Exception {
CoordinateReferenceSystem utm1N = CRS.decode("EPSG:32601");
Please sign in to comment.
Something went wrong with that request. Please try again.