Skip to content

Commit 28b2d4a

Browse files
Langston Smithlangsmith
authored andcommitted
initial additions
1 parent efb6c7f commit 28b2d4a

3 files changed

Lines changed: 190 additions & 1 deletion

File tree

docs/turf-port.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Below's an on going list of the Turf functions which currently exist inside the
5757
- [ ] turf-voronoi
5858

5959
## Feature Conversion
60-
- [ ] turf-combine
60+
- [X] turf-combine
6161
- [x] turf-explode
6262
- [ ] turf-flatten
6363
- [ ] turf-line-to-polygon

services-turf/src/main/java/com/mapbox/turf/TurfConversion.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@
77
import com.mapbox.geojson.Feature;
88
import com.mapbox.geojson.FeatureCollection;
99
import com.mapbox.geojson.Point;
10+
import com.mapbox.geojson.Geometry;
11+
import com.mapbox.geojson.LineString;
12+
import com.mapbox.geojson.MultiLineString;
13+
import com.mapbox.geojson.MultiPoint;
14+
import com.mapbox.geojson.MultiPolygon;
15+
import com.mapbox.geojson.Polygon;
1016
import com.mapbox.turf.TurfConstants.TurfUnitCriteria;
1117

1218
import java.util.ArrayList;
19+
import java.util.Arrays;
1320
import java.util.HashMap;
1421
import java.util.List;
1522
import java.util.Map;
@@ -200,5 +207,61 @@ public static FeatureCollection explode(@NonNull Feature feature) {
200207
finalFeatureList.add(Feature.fromGeometry(singlePoint));
201208
}
202209
return FeatureCollection.fromFeatures(finalFeatureList);
210+
211+
}
212+
213+
/**
214+
* Combines a FeatureCollection of all {@link Point}s , {@link LineString}s,
215+
* or {@link Polygon} features into {@link MultiPoint}, {@link MultiLineString},
216+
* or {@link MultiPolygon}.
217+
*
218+
* @param featureCollection a {@link FeatureCollection} that has {@link Feature}
219+
* objects which are all {@link Point}, {@link LineString},
220+
* or {@link Polygon} geometries.
221+
* @return a {@link FeatureCollection} which has a {@link Feature}.
222+
* The {@link Feature} can be used to cast {@link MultiPoint},
223+
* {@link MultiLineString}, or {@link MultiPolygon}
224+
* @since 4.8.0
225+
*/
226+
public static FeatureCollection combine(@NonNull FeatureCollection featureCollection) {
227+
Geometry firstFeatureGeometry = featureCollection.features().get(0).geometry();
228+
if (firstFeatureGeometry instanceof Point) {
229+
return FeatureCollection.fromFeature(Feature.fromGeometry(
230+
MultiPoint.fromLngLats(listOfPoints(featureCollection))));
231+
} else if (firstFeatureGeometry instanceof LineString) {
232+
return FeatureCollection.fromFeature(Feature.fromGeometry(
233+
MultiLineString.fromLngLats(Arrays.asList(listOfPoints(featureCollection)))
234+
));
235+
} else if (firstFeatureGeometry instanceof Polygon) {
236+
List<Polygon> polygonList = new ArrayList<>();
237+
for (Feature singleFeature : featureCollection.features()) {
238+
if (singleFeature.geometry() instanceof Polygon) {
239+
polygonList.add((Polygon) singleFeature.geometry());
240+
} else {
241+
throw new TurfException("Your FeatureCollection must be of all of "
242+
+ "the same geometry type.");
243+
}
244+
}
245+
return FeatureCollection.fromFeature(Feature.fromGeometry(
246+
MultiPolygon.fromPolygons(polygonList)));
247+
}
248+
throw new TurfException("Your FeatureCollection did not include "
249+
+ "a Point, LineString, or Polygon geometry type. Please pass in "
250+
+ "a FeatureCollection with two or more Features which are all of "
251+
+ "the same geometry type.");
252+
}
253+
254+
private static List<Point> listOfPoints(FeatureCollection featureCollection) {
255+
List<Point> pointList = new ArrayList<>();
256+
for (Feature singleFeature : featureCollection.features()) {
257+
if (singleFeature.geometry() instanceof Point) {
258+
pointList.add(TurfMeta.getCoord(singleFeature));
259+
} else if (singleFeature.geometry() instanceof LineString) {
260+
pointList.addAll(TurfMeta.coordAll((LineString) singleFeature.geometry()));
261+
} else if (singleFeature.geometry() instanceof Polygon) {
262+
pointList.addAll(TurfMeta.coordAll((Polygon) singleFeature.geometry(), true));
263+
}
264+
}
265+
return pointList;
203266
}
204267
}

services-turf/src/test/java/com/mapbox/turf/TurfConversionTest.java

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
import java.io.IOException;
1818
import java.util.Arrays;
1919

20+
import static org.hamcrest.CoreMatchers.startsWith;
2021
import static org.junit.Assert.assertEquals;
22+
import static org.junit.Assert.assertNotNull;
2123

2224
public class TurfConversionTest extends TestUtils {
2325

@@ -78,6 +80,130 @@ public void convertDistance() throws TurfException {
7880
TurfConstants.UNIT_CENTIMETERS), DELTA);
7981
}
8082

83+
@Test
84+
public void combinePointsToMultiPoint() throws Exception {
85+
FeatureCollection pointFeatureCollection =
86+
FeatureCollection.fromFeatures(
87+
new Feature[]{
88+
Feature.fromGeometry(Point.fromLngLat(-2.46,
89+
27.6835)),
90+
Feature.fromGeometry(Point.fromLngLat(41.83,
91+
7.3624)),
92+
});
93+
94+
FeatureCollection featureCollectionWithNewMultiPointObject = TurfConversion.combine(pointFeatureCollection);
95+
assertNotNull(featureCollectionWithNewMultiPointObject);
96+
97+
MultiPoint multiPoint = (MultiPoint) featureCollectionWithNewMultiPointObject.features().get(0).geometry();
98+
assertNotNull(multiPoint);
99+
100+
assertEquals(-2.46, multiPoint.coordinates().get(0).longitude(), DELTA);
101+
assertEquals(27.6835, multiPoint.coordinates().get(0).latitude(), DELTA);
102+
assertEquals(41.83, multiPoint.coordinates().get(1).longitude(), DELTA);
103+
assertEquals(7.3624, multiPoint.coordinates().get(1).latitude(), DELTA);
104+
}
105+
106+
@Test
107+
public void combineLineStringToMultiLineString() throws Exception {
108+
FeatureCollection lineStringFeatureCollection =
109+
FeatureCollection.fromFeatures(
110+
new Feature[]{
111+
Feature.fromGeometry(LineString.fromLngLats(
112+
Arrays.asList(Point.fromLngLat(-11.25, 55.7765),
113+
Point.fromLngLat(41.1328, 22.91792)))),
114+
Feature.fromGeometry(LineString.fromLngLats(
115+
Arrays.asList(Point.fromLngLat(3.8671, 19.3111),
116+
Point.fromLngLat(20.742, -20.3034))))
117+
});
118+
119+
FeatureCollection featureCollectionWithNewMultiLineStringObject = TurfConversion.combine(lineStringFeatureCollection);
120+
assertNotNull(featureCollectionWithNewMultiLineStringObject);
121+
122+
MultiLineString multiLineString = (MultiLineString) featureCollectionWithNewMultiLineStringObject.features().get(0).geometry();
123+
assertNotNull(multiLineString);
124+
125+
// Checking the first LineString in the MultiLineString
126+
assertEquals(-11.25, multiLineString.coordinates().get(0).get(0).longitude(), DELTA);
127+
assertEquals(55.7765, multiLineString.coordinates().get(0).get(0).latitude(), DELTA);
128+
129+
// Checking the second LineString in the MultiLineString
130+
assertEquals(41.1328, multiLineString.coordinates().get(0).get(1).longitude(), DELTA);
131+
assertEquals(22.91792, multiLineString.coordinates().get(0).get(1).latitude(), DELTA);
132+
}
133+
134+
@Test
135+
public void combinePolygonToMultiPolygon() throws Exception {
136+
FeatureCollection polygonFeatureCollection =
137+
FeatureCollection.fromFeatures(
138+
new Feature[]{
139+
Feature.fromGeometry(Polygon.fromLngLats(Arrays.asList(
140+
Arrays.asList(
141+
Point.fromLngLat(61.938950426660604, 5.9765625),
142+
Point.fromLngLat(52.696361078274485, 33.046875),
143+
Point.fromLngLat(69.90011762668541, 28.828124999999996),
144+
Point.fromLngLat(61.938950426660604, 5.9765625))))),
145+
Feature.fromGeometry(Polygon.fromLngLats(Arrays.asList(
146+
Arrays.asList(
147+
Point.fromLngLat(11.42578125, 16.636191878397664),
148+
Point.fromLngLat(7.91015625, -9.102096738726443),
149+
Point.fromLngLat(31.113281249999996, 17.644022027872726),
150+
Point.fromLngLat(11.42578125, 16.636191878397664)
151+
))))
152+
});
153+
154+
FeatureCollection featureCollectionWithNewMultiPolygonObject = TurfConversion.combine(polygonFeatureCollection);
155+
assertNotNull(featureCollectionWithNewMultiPolygonObject);
156+
157+
MultiPolygon multiPolygon = (MultiPolygon) featureCollectionWithNewMultiPolygonObject.features().get(0).geometry();
158+
assertNotNull(multiPolygon);
159+
160+
// Checking the first Polygon in the MultiPolygon
161+
162+
// Checking the first Point
163+
assertEquals(61.938950426660604, multiPolygon.coordinates().get(0).get(0).get(0).longitude(), DELTA);
164+
assertEquals(5.9765625, multiPolygon.coordinates().get(0).get(0).get(0).latitude(), DELTA);
165+
166+
// Checking the second Point
167+
assertEquals(52.696361078274485, multiPolygon.coordinates().get(0).get(0).get(1).longitude(), DELTA);
168+
assertEquals(33.046875, multiPolygon.coordinates().get(0).get(0).get(1).latitude(), DELTA);
169+
170+
// Checking the second Polygon in the MultiPolygon
171+
172+
// Checking the first Point
173+
assertEquals(11.42578125, multiPolygon.coordinates().get(1).get(0).get(0).longitude(), DELTA);
174+
assertEquals(16.636191878397664, multiPolygon.coordinates().get(1).get(0).get(0).latitude(), DELTA);
175+
176+
// Checking the second Point
177+
assertEquals(7.91015625, multiPolygon.coordinates().get(1).get(0).get(1).longitude(), DELTA);
178+
assertEquals(-9.102096738726443, multiPolygon.coordinates().get(1).get(0).get(1).latitude(), DELTA);
179+
}
180+
181+
// TODO: Add test that checks Feature amount
182+
@Test
183+
public void geometryTypeMixThrowsException() throws Exception {
184+
thrown.expect(TurfException.class);
185+
thrown.expectMessage(startsWith("Your FeatureCollection must be of all of " +
186+
"the same geometry type."));
187+
188+
// Create a FeatureCollection with a Point Feature and a Polygon Feature
189+
FeatureCollection pointAndPolygonFeatureCollection =
190+
FeatureCollection.fromFeatures(
191+
new Feature[]{
192+
Feature.fromGeometry(Point.fromLngLat(-2.46,
193+
27.6835)),
194+
Feature.fromGeometry(Polygon.fromLngLats(Arrays.asList(
195+
Arrays.asList(
196+
Point.fromLngLat(11.42578125, 16.636191878397664),
197+
Point.fromLngLat(7.91015625, -9.102096738726443),
198+
Point.fromLngLat(31.113281249999996, 17.644022027872726),
199+
Point.fromLngLat(11.42578125, 16.636191878397664)
200+
))))
201+
});
202+
203+
// Building a geometry with this FeatureCollection should through an error
204+
FeatureCollection newMultiPolygonObject = TurfConversion.combine(pointAndPolygonFeatureCollection);
205+
}
206+
81207
@Test
82208
public void explodePointSingleFeature() throws IOException, NullPointerException {
83209
Point point = Point.fromLngLat(102, 0.5);

0 commit comments

Comments
 (0)