@SuppressWarnings("unchecked") public static PointFeature fromJsonNode(JsonNode feature) throws EmptyPolygonException, UnsupportedGeometryException { Feature geoJsonFeature; try { geoJsonFeature = deserializer.readValue(feature.traverse(), Feature.class); } catch (IOException e) { throw new UnsupportedGeometryException(e.getMessage()); } PointFeature ret = new PointFeature(geoJsonFeature.getId()); ret.setGeom(GeometryUtils.convertGeoJsonToJtsGeometry(geoJsonFeature.getGeometry())); Object structured = geoJsonFeature.getProperty("structured"); if (structured == null || !(structured instanceof Map)) return null; // The code below assume the structured map to have integers only ret.setAttributes((Map<String, Integer>)(structured)); return ret; }
@SuppressWarnings("unchecked") protected static <V> V propertyOrDefault(Feature feature, String propertyName, V defaultValue) { return (feature.getProperty(propertyName) == null) ? defaultValue : (V)feature.getProperty(propertyName); } }
private String getProperty(Feature feature, String propertyName) { Object property = feature.getProperty(propertyName); return property != null ? trim(property.toString()) : ""; }
private static POI toPoi(Feature feature) { LngLatAlt coordinates = ((Point)feature.getGeometry()).getCoordinates(); Map<String, String> osmTags = feature.getProperty("osmTags"); if (osmTags == null) osmTags = new HashMap<>(); String openingHours = osmTags.get("opening_hours"); if (openingHours != null) openingHours = openingHours.replaceAll("; *", "\n"); String website = feature.getProperty("website"); if (TextUtils.isEmpty(website)) website = osmTags.get("url"); return new POI(Integer.parseInt(feature.getProperty("id")), feature.getProperty("name"), feature.getProperty("notes"), website, osmTags.get("phone"), openingHours, coordinates.getLatitude(), coordinates.getLongitude()); }
/** * {@code placeId} is a unique identifier for a place. * * @return the placeId */ @Transient public String getPlaceId() { final Feature location = getLocation(); if (location == null) { return null; } return location.getProperty("placeId"); }
/** * {@code postcodeLocalities} is an array denoting all the localities * contained in a postal code. This is only present when the result is a * postal code that contains multiple localities. * * @return the postcode localities */ @Transient public String[] getPostcodeLocalities() { final Feature location = getLocation(); if (location == null) { return null; } return location.getProperty("postcodeLocalities"); }
/** * {@code formattedAddress} is the human-readable address of this location. * Often this address is equivalent to the "postal address," which sometimes * differs from country to country. (Note that some countries, such as the * United Kingdom, do not allow distribution of true postal addresses due to * licensing restrictions.) This address is generally composed of one or * more address components. For example, the address "111 8th Avenue, New * York, NY" contains separate address components for "111" (the street * number, "8th Avenue" (the route), "New York" (the city) and "NY" (the US * state). These address components contain additional information. * * @return the formatted address */ @Transient public String getFormattedAddress() { final Feature location = getLocation(); if (location == null) { return null; } return location.getProperty("formattedAddress"); }
/** * {@code partialMatch} indicates that the geocoder did not return an exact * match for the original request, though it was able to match part of the * requested address. You may wish to examine the original request for * misspellings and/or an incomplete address. * * <p> * Partial matches most often occur for street addresses that do not exist * within the locality you pass in the request. Partial matches may also be * returned when a request matches two or more locations in the same * locality. For example, "21 Henr St, Bristol, UK" will return a partial * match for both Henry Street and Henrietta Street. Note that if a request * includes a misspelled address component, the geocoding service may * suggest an alternate address. Suggestions triggered in this way will not * be marked as a partial match. * * @return the partialMatch */ @Transient public boolean isPartialMatch() { final Feature location = getLocation(); if (location == null) { return false; } return location.getProperty("partialMatch"); }
private static Photo toPhoto(Feature feature) { LngLatAlt coordinates = ((Point)feature.getGeometry()).getCoordinates(); GeoPoint geoPoint = new GeoPoint(coordinates.getLatitude(), coordinates.getLongitude()); return new Photo(propertyOrDefault(feature, "id", -1), propertyOrDefault(feature, "categoryId", "Not known"), propertyOrDefault(feature, "metacategoryId", "Not known"), (String)feature.getProperty("caption"), (String)feature.getProperty("shortlink"), (String)feature.getProperty("thumbnailUrl"), geoPoint, toVideos(propertyOrDefault(feature, "videoFormats", Collections.<String, Object>emptyMap()))); }
private List<NavigationPosition> extractPositions(List<Feature> features) { List<NavigationPosition> result = new ArrayList<>(features.size()); for (Feature feature : features) { GeoJsonObject geometry = feature.getGeometry(); if (!(geometry instanceof Point)) continue; Point point = (Point) geometry; LngLatAlt lngLatAlt = point.getCoordinates(); String type = feature.getProperty("osm_key"); result.add(new SimpleNavigationPosition(lngLatAlt.getLongitude(), lngLatAlt.getLatitude(), null, getDisplayName(feature) + " (" + type + ")")); } return result; }
/** * @param geometry geometry object to fill in * @param location the location to fill it with */ private void populateLocation(final Geometry geometry, final Feature location) { if (location == null) { geometry.location = null; geometry.locationType = null; } else { geometry.location = toLatLng((Point) location.getGeometry()); geometry.locationType = toLocationType(location.getProperty("locationType")); } }
private static GeoPlace toGeoPlace(Feature feature) { LngLatAlt coordinates = ((Point)feature.getGeometry()).getCoordinates(); return new GeoPlace(new GeoPoint(coordinates.getLatitude(), coordinates.getLongitude()), (String)feature.getProperty("name"), (String)feature.getProperty("near")); } }
@Test public void writes_the_GeoJSON_file() throws IOException { List<Feature> outputFeatures = IntStream.range(0, 1000).mapToObj(i -> buildFeature()).collect(Collectors.toList()); GeoJson.write(output, outputFeatures.stream()); FeatureCollection parsedFeatureCollection = new ObjectMapper().readValue(Files.newInputStream(output), FeatureCollection.class); List<Feature> actualFeatures = parsedFeatureCollection.getFeatures(); assertThat(actualFeatures, hasSize(1000)); assertThat(actualFeatures, allMatch(feature -> feature.getGeometry() instanceof Point)); assertThat(actualFeatures, allMatch(feature -> ((Point) feature.getGeometry()).getCoordinates() != null)); assertThat(actualFeatures, allMatch(feature -> feature.getProperties().containsKey("key") && feature.getProperty("key") != null)); assertThat(actualFeatures, allMatch(feature -> feature.getProperties().containsKey("field") && feature.getProperty("field").equals("some-field"))); assertThat(actualFeatures, allMatch(feature -> feature.getProperties().containsKey("empty") && feature.getProperty("empty").equals("no"))); assertThat(actualFeatures, allMatch(feature -> feature.getProperties().containsKey("valid") && feature.getProperty("valid").equals("yes"))); }
@Test public void handles_invalid_GEOTRACE_values() throws IOException, XmlPullParserException { List<Feature> features = getFeatures( Pair.of(GEOTRACE, "1 2") // we expect at least a GEOPOINT ); assertThat(features, hasSize(1)); assertThat(features, allMatch(feature -> feature.getGeometry() == null)); assertThat(features, allMatch(feature -> feature.getProperty("empty") == "no")); assertThat(features, allMatch(feature -> feature.getProperty("valid") == "no")); }
@Test public void transforms_a_submission_to_a_feature_list() throws IOException, XmlPullParserException { Map<String, Feature> features = getFeatures( Pair.of(GEOPOINT, "1 2 3"), Pair.of(GEOTRACE, "1 2;3 4"), Pair.of(GEOSHAPE, "1 2;3 4;5 6;1 2") ).stream().collect(toMap( f -> f.getProperty("field"), f -> f )); assertThat(features.values(), hasSize(3)); assertThat(features.values(), allMatch(feature -> feature.getProperty("key").equals("uuid:39f3dd36-161e-45cb-a1a4-395831d253a7"))); assertThat(features.values(), allMatch(feature -> feature.getProperty("empty").equals("no"))); assertThat(features.get("some-field-1").getGeometry(), is(new Point(2, 1, 3))); assertThat(features.get("some-field-2").getGeometry(), is(new LineString(new LngLatAlt(2, 1), new LngLatAlt(4, 3)))); assertThat(features.get("some-field-3").getGeometry(), is(new Polygon(new LngLatAlt(2, 1), new LngLatAlt(4, 3), new LngLatAlt(6, 5), new LngLatAlt(2, 1)))); }
@Test public void handles_empty_spatial_fields() throws IOException, XmlPullParserException { List<Feature> features = getFeatures( Pair.of(GEOPOINT, ""), Pair.of(GEOTRACE, ""), Pair.of(GEOSHAPE, "") ); assertThat(features, hasSize(3)); assertThat(features, allMatch(feature -> feature.getGeometry() == null)); assertThat(features, allMatch(feature -> feature.getProperty("empty").equals("yes"))); }
@Test public void handles_invalid_GEOSHAPE_values() throws IOException, XmlPullParserException { List<Feature> features = getFeatures( Pair.of(GEOSHAPE, "1 2"), // we expect at least four GEOPOINTS Pair.of(GEOSHAPE, "1 2;2 3"), // we expect at least four GEOPOINTS Pair.of(GEOSHAPE, "1 2;2 3;4 5"), // we expect at least four GEOPOINTS Pair.of(GEOSHAPE, "1 2;2 3;4 5;6 7") // we expect the first and last GEOPOINTS to be the same ); assertThat(features, hasSize(4)); assertThat(features, allMatch(feature -> feature.getGeometry() == null)); assertThat(features, allMatch(feature -> feature.getProperty("empty") == "no")); assertThat(features, allMatch(feature -> feature.getProperty("valid") == "no")); }
@Test public void handles_invalid_GEOPOINT_values() throws IOException, XmlPullParserException { List<Feature> features = getFeatures( Pair.of(GEOPOINT, "a"), // we expect doubles Pair.of(GEOPOINT, "1"), // we expect at least two values Pair.of(GEOPOINT, "1 2 3 4 5"), // we expect at most 4 values Pair.of(GEOPOINT, "1 2;3 4"), // we dont' expect a string of points Pair.of(GEOPOINT, "91 2"), // we dont' expect latitudes greater than 90 Pair.of(GEOPOINT, "-91 2"), // we dont' expect latitudes less than -90 Pair.of(GEOPOINT, "1 181"), // we dont' expect latitudes greater than 180 Pair.of(GEOPOINT, "1 -181") // we dont' expect latitudes less than -180 ); assertThat(features, hasSize(8)); assertThat(features, allMatch(feature -> feature.getGeometry() == null)); assertThat(features, allMatch(feature -> feature.getProperty("empty") == "no")); assertThat(features, allMatch(feature -> feature.getProperty("valid") == "no")); }