ArrowLineLayer extends KujakuLayer { private FeatureCollection generateArrowHeadFeatureCollection(@NonNull LineString lineString) { ArrayList<Feature> featureList = new ArrayList<>(); List<Point> lineStringPoints = lineString.coordinates(); for (int i = 0; i < lineStringPoints.size() - 1; i++) { Point startPoint = lineStringPoints.get(i); Point endPoint = lineStringPoints.get(i + 1); Feature arrowHeadFeature = Feature.fromGeometry(TurfMeasurement.midpoint(startPoint, endPoint)); arrowHeadFeature.addNumberProperty(ARROW_HEAD_BEARING, TurfMeasurement.bearing(startPoint, endPoint)); featureList.add(arrowHeadFeature); } return FeatureCollection.fromFeatures(featureList); } private  ArrowLineLayer(@NonNull Builder builder); LineLayer getLineLayer(); SymbolLayer getArrowHeadLayer(); @Override void addLayerToMap(@NonNull MapboxMap mapboxMap); @Override void enableLayerOnMap(@NonNull MapboxMap mapboxMap); @Override void disableLayerOnMap(@NonNull MapboxMap mapboxMap); @Override @NonNull String[] getLayerIds(); @Override boolean removeLayerOnMap(@NonNull MapboxMap mapboxMap); @Override void updateFeatures(@NonNull FeatureCollection featureCollection); static Point getCenter(@NonNull Geometry featureGeometry); @Override FeatureCollection getFeatureCollection(); static final String ARROW_HEAD_BEARING; static final int MIN_ARROW_ZOOM; static final int MAX_ARROW_ZOOM; static final float MIN_ZOOM_ARROW_HEAD_SCALE; static final float MAX_ZOOM_ARROW_HEAD_SCALE; }
@Test public void generateArrowHeadFeatureCollection() throws InvalidArrowLineConfigException { ArrayList<Point> pointsList = new ArrayList<>(); pointsList.add(Point.fromLngLat(9.1d, 9.1d)); pointsList.add(Point.fromLngLat(11.1d, 9.1d)); pointsList.add(Point.fromLngLat(11.1d, 2.1d)); pointsList.add(Point.fromLngLat(9.1d, 2.1d)); LineString lineString = LineString.fromLngLats(pointsList); ArrowLineLayer.FeatureConfig featureConfig = new ArrowLineLayer.FeatureConfig( FeatureCollection.fromFeature(Feature.fromGeometry(lineString)) ); ArrowLineLayer.SortConfig sortConfig = new ArrowLineLayer.SortConfig("", ArrowLineLayer.SortConfig.SortOrder.DESC, ArrowLineLayer.SortConfig.PropertyType.NUMBER); ArrowLineLayer.Builder builder = new ArrowLineLayer.Builder(context, featureConfig, sortConfig); ArrowLineLayer arrowLineLayer = builder.build(); FeatureCollection arrowHeadFeatureCollection = ReflectionHelpers.callInstanceMethod(arrowLineLayer , "generateArrowHeadFeatureCollection" , ReflectionHelpers.ClassParameter.from(LineString.class, lineString) ); assertEquals(3, arrowHeadFeatureCollection.features().size()); Feature arrowHeadFeature = arrowHeadFeatureCollection.features().get(0); assertTrue(arrowHeadFeature.hasProperty("arrow-head-bearing")); assertTrue(arrowHeadFeature.hasNonNullValueForProperty("arrow-head-bearing")); Point expectedPoint = Point.fromLngLat(10.1d, 9.101363d); Point actual = (Point) arrowHeadFeatureCollection.features().get(0).geometry(); assertEquals(expectedPoint.latitude(), actual.latitude(), 0.0000001d); assertEquals(expectedPoint.longitude(), actual.longitude(), 0d); }