Skip to content

Commit

Permalink
[GEOT-5446] SimpleFeatureImpl.equals fails to tell apart features wit…
Browse files Browse the repository at this point in the history
…h same 2d ordinates, but different z
  • Loading branch information
aaime committed Jun 21, 2016
1 parent f7934f6 commit 7039708
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 3 deletions.
Expand Up @@ -34,6 +34,7 @@
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.geometry.jts.ReferencedEnvelope3D;
import org.geotools.geometry.jts.coordinatesequence.CoordinateSequences;
import org.geotools.util.Converters;
import org.geotools.util.Utilities;
import org.opengis.feature.GeometryAttribute;
Expand All @@ -50,6 +51,7 @@
import org.opengis.geometry.BoundingBox;
import org.opengis.referencing.crs.CoordinateReferenceSystem;

import com.vividsolutions.jts.geom.CoordinateSequenceComparator;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;

Expand Down Expand Up @@ -446,9 +448,15 @@ public boolean equals(Object obj) {
return false;
}
} else {
if (!values[i].equals(otherAtt)) {
if(values[i] instanceof Geometry) {
if(!(otherAtt instanceof Geometry)) {
return false;
} else if(!CoordinateSequences.equalsND((Geometry) values[i], (Geometry) otherAtt)) {
return false;
}
} else if (!values[i].equals(otherAtt)) {
return false;
}
}
}
}

Expand Down
Expand Up @@ -18,11 +18,15 @@
*/
package org.geotools.geometry.jts.coordinatesequence;

import java.util.ArrayList;
import java.util.List;

import org.geotools.geometry.jts.CurvedGeometry;

import com.vividsolutions.jts.algorithm.RobustDeterminant;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.CoordinateSequenceComparator;
import com.vividsolutions.jts.geom.CoordinateSequenceFilter;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
Expand Down Expand Up @@ -197,6 +201,44 @@ public static int coordinateDimension(CoordinateSequence seq)
}
return 3;
}

/**
* Returns true if the two geometries are equal in N dimensions (normal geometry equality is only 2D)
* @param g1
* @param g2
* @return
*/
public static boolean equalsND(Geometry g1, Geometry g2) {
// if not even in 2d, they are not equal
if(!g1.equals(g2)) {
return false;
}
int dim1 = coordinateDimension(g1);
int dim2 = coordinateDimension(g2);
if(dim1 != dim2) {
return false;
}
if(dim1 == 2) {
return true;
}

// ok, 2d equal, it means they have the same list of geometries and coordinate sequences, in the same order
List<CoordinateSequence> sequences1 = CoordinateSequenceCollector.find(g1);
List<CoordinateSequence> sequences2 = CoordinateSequenceCollector.find(g2);
if(sequences1.size() != sequences2.size()) {
return false;
}
CoordinateSequenceComparator comparator = new CoordinateSequenceComparator();
for (int i = 0; i < sequences1.size(); i++) {
CoordinateSequence cs1 = sequences1.get(i);
CoordinateSequence cs2 = sequences2.get(i);
if(comparator.compare(cs1, cs2) != 0) {
return false;
}
}

return true;
}

private static class CoordinateSequenceFinder implements CoordinateSequenceFilter {

Expand Down Expand Up @@ -233,4 +275,33 @@ public boolean isGeometryChanged() {
}

}

private static class CoordinateSequenceCollector implements CoordinateSequenceFilter {

public static List<CoordinateSequence> find(Geometry g) {
CoordinateSequenceCollector finder = new CoordinateSequenceCollector();
g.apply(finder);
return finder.getSequences();
}

private List<CoordinateSequence> sequences = new ArrayList<>();

public List<CoordinateSequence> getSequences() {
return sequences;
}

public void filter(CoordinateSequence seq, int i) {
sequences.add(seq);

}

public boolean isDone() {
return false;
}

public boolean isGeometryChanged() {
return false;
}

}
}
Expand Up @@ -18,12 +18,17 @@

import junit.framework.TestCase;

import static org.junit.Assert.assertNotEquals;

import org.geotools.data.DataUtilities;
import org.opengis.feature.GeometryAttribute;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.GeometryDescriptor;

import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;

/**
*
*
Expand All @@ -33,12 +38,14 @@ public class SimpleFeatureImplTest extends TestCase {

SimpleFeatureType schema;
SimpleFeature feature;
WKTReader wkt;

@Override
protected void setUp() throws Exception {
super.setUp();
schema = DataUtilities.createType("buildings", "the_geom:MultiPolygon,name:String,ADDRESS:String");
schema = DataUtilities.createType("buildings", "the_geom:Geometry,name:String,ADDRESS:String");
feature = SimpleFeatureBuilder.build(schema, new Object[] {null, "ABC", "Random Road, 12"}, "building.1");
wkt = new WKTReader();
}

// see GEOT-2061
Expand Down Expand Up @@ -91,4 +98,23 @@ public void testSetValue() {
assertEquals(feature.getAttribute(i), myFeature.getAttribute(i));
}
}

public void testCompare2D() throws ParseException {
SimpleFeature f1 = SimpleFeatureBuilder.build(schema, new Object[] {wkt.read("POINT(1 2)"), "ABC", "Random Road, 12"}, "building.1");
SimpleFeature f2 = SimpleFeatureBuilder.build(schema, new Object[] {wkt.read("POINT(1 2)"), "ABC", "Random Road, 12"}, "building.1");
SimpleFeature f3 = SimpleFeatureBuilder.build(schema, new Object[] {wkt.read("POINT(3 4)"), "ABC", "Random Road, 12"}, "building.1");
assertEquals(f1, f2);
assertNotEquals(f1, f3);
}

public void testCompare3D() throws ParseException {
SimpleFeature f1 = SimpleFeatureBuilder.build(schema, new Object[] {wkt.read("POINT(1 2)"), "ABC", "Random Road, 12"}, "building.1");
SimpleFeature f2 = SimpleFeatureBuilder.build(schema, new Object[] {wkt.read("POINT(1 2 15)"), "ABC", "Random Road, 12"}, "building.1");
SimpleFeature f3 = SimpleFeatureBuilder.build(schema, new Object[] {wkt.read("POINT(1 2 18)"), "ABC", "Random Road, 12"}, "building.1");
SimpleFeature f4 = SimpleFeatureBuilder.build(schema, new Object[] {wkt.read("POINT(1 2 18)"), "ABC", "Random Road, 12"}, "building.1");
assertNotEquals(f1, f2);
assertNotEquals(f1, f3);
assertNotEquals(f2, f3);
assertEquals(f3, f4);
}
}
@@ -1,6 +1,8 @@
package org.geotools.geometry.jts.coordinatesequence;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.geotools.geometry.jts.GeometryBuilder;
import org.geotools.geometry.jts.LiteCoordinateSequence;
Expand Down Expand Up @@ -111,4 +113,22 @@ public void testCoordinateDimensionGeometryCollectionEmpty() {
assertEquals(3, CoordinateSequences.coordinateDimension(geom));
}

@Test
public void testEqualityND() {
Geometry g1 = liteGF.createPolygon(
liteGF.createLinearRing(liteCSF.create(new double[] { 1, 1, 100, 2, 1, 99, 2, 2,
98, 1, 2, 97, 1, 1, 100 }, 3)), null);
Geometry g2 = liteGF.createPolygon(
liteGF.createLinearRing(liteCSF.create(new double[] { 1, 1, 2, 1, 2, 2,
1, 2, 1, 1 }, 2)), null);
Geometry g3 = liteGF.createPolygon(
liteGF.createLinearRing(liteCSF.create(new double[] { 1, 1, 200, 2, 1, 199, 2, 2,
198, 1, 2, 197, 1, 1, 200 }, 3)), null);
Geometry g4 = liteGF.createPolygon(
liteGF.createLinearRing(liteCSF.create(new double[] { 1, 1, 100, 2, 1, 99, 2, 2,
98, 1, 2, 97, 1, 1, 100 }, 3)), null);
assertTrue(CoordinateSequences.equalsND(g1, g4));
assertFalse(CoordinateSequences.equalsND(g1, g2));
assertFalse(CoordinateSequences.equalsND(g1, g3));
}
}

0 comments on commit 7039708

Please sign in to comment.