Search in sources :

Example 1 with MultiPolygon

use of org.openstreetmap.atlas.geography.MultiPolygon in project atlas-generator by osmlab.

the class AtlasMissingShardVerifier method verifier.

public int verifier(final CountryBoundaryMap boundaries, final Set<CountryShard> missingCountryShardsUntrimmed, final File output, final String server, final HttpHost proxy, final ConfiguredTaggableFilter filter, final Integer numRetryQueries) {
    int returnCode = 0;
    final Set<CountryShard> missingCountryShards = removeShardsWithZeroIntersection(missingCountryShardsUntrimmed, boundaries);
    final String masterQuery = createMasterQuery(boundaries, missingCountryShards);
    final OverpassClient client = new OverpassClient(server, proxy);
    try (SafeBufferedWriter writer = output.writer()) {
        final List<OverpassOsmNode> nodes = client.nodesFromQuery(masterQuery);
        final List<OverpassOsmWay> ways = client.waysFromQuery(masterQuery);
        if (client.hasTooMuchResponseData()) {
            logger.warn("The overpass query returned too much data. This means that there's potentially" + "large amounts of data missing! Rerunning with smaller queries.");
            client.resetTooMuchDataError();
            final StringList splitQueries = createQueryList(boundaries, missingCountryShards, numRetryQueries);
            nodes.clear();
            ways.clear();
            for (final String query : splitQueries) {
                nodes.addAll(client.nodesFromQuery(query));
                ways.addAll(client.waysFromQuery(query));
            }
        }
        if (client.hasTooMuchResponseData()) {
            throw new CoreException("The overpass query had to much data, even when split " + numRetryQueries + " times. There is lots of data missing!");
        }
        if (client.hasUnknownError()) {
            throw new CoreException("The overpass query encountered an error. Validation has failed.");
        }
        final STRtree nodeTree = initializeNodeTree(nodes);
        final STRtree wayTree = initializeWayTree(nodes, ways);
        for (final CountryShard countryShard : missingCountryShards) {
            final Clip clip = intersectionClip(countryShard, boundaries);
            final MultiPolygon clipMulti = clip.getClipMultiPolygon();
            final Rectangle clipBounds = clipMulti.bounds();
            @SuppressWarnings("unchecked") final List<OverpassOsmNode> nodeList = nodeTree.query(clipBounds.asEnvelope());
            // Prune extra nodes returned by STRtree that might not actually be contained within
            // clipBounds
            nodeList.removeIf(node -> !clipBounds.fullyGeometricallyEncloses(Location.forString(node.getLatitude() + "," + node.getLongitude())));
            @SuppressWarnings("unchecked") final List<OverpassOsmWay> wayList = wayTree.query(clipBounds.asEnvelope());
            // Filter out ways that aren't ingested into atlas
            wayList.stream().filter(way -> !filter.test(Taggable.with(way.getTags()))).forEach(way -> {
                nodeList.removeIf(node -> way.getNodeIdentifiers().contains(node.getIdentifier()));
            });
            // bounds then the shard should have been built, so break and list the shard
            for (final OverpassOsmNode node : nodeList) {
                final Location nodeLocation = Location.forString(node.getLatitude() + "," + node.getLongitude());
                if (clipMulti.fullyGeometricallyEncloses(nodeLocation)) {
                    returnCode = -1;
                    writer.writeLine(countryShard.toString());
                    writer.writeLine("Boundary/Shard intersection zone: " + clipMulti.toString());
                    writer.writeLine("Id of node that should have been imported: " + node.getIdentifier());
                    writer.writeLine("Node Location: " + nodeLocation.toString() + "\n");
                    logger.info("{} is missing!", countryShard);
                    break;
                }
            }
        }
    } catch (final Exception e) {
        logger.error("Error!", e);
        return -1;
    }
    if (returnCode == 0) {
        logger.info("No shards are missing!");
    }
    return returnCode;
}
Also used : StandardConfiguration(org.openstreetmap.atlas.utilities.configuration.StandardConfiguration) LoggerFactory(org.slf4j.LoggerFactory) Coordinate(org.locationtech.jts.geom.Coordinate) HashMap(java.util.HashMap) ConfiguredTaggableFilter(org.openstreetmap.atlas.tags.filters.ConfiguredTaggableFilter) ArrayList(java.util.ArrayList) CountryShard(org.openstreetmap.atlas.geography.sharding.CountryShard) AtlasGeneratorParameters(org.openstreetmap.atlas.generator.AtlasGeneratorParameters) ClipType(org.openstreetmap.atlas.geography.clipping.Clip.ClipType) Clip(org.openstreetmap.atlas.geography.clipping.Clip) StringConverter(org.openstreetmap.atlas.utilities.conversion.StringConverter) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) CountryBoundaryMap(org.openstreetmap.atlas.geography.boundary.CountryBoundaryMap) Command(org.openstreetmap.atlas.utilities.runtime.Command) File(org.openstreetmap.atlas.streaming.resource.File) Logger(org.slf4j.Logger) Maps(org.openstreetmap.atlas.utilities.collections.Maps) CoreException(org.openstreetmap.atlas.exception.CoreException) Location(org.openstreetmap.atlas.geography.Location) Set(java.util.Set) CommandMap(org.openstreetmap.atlas.utilities.runtime.CommandMap) Collectors(java.util.stream.Collectors) SafeBufferedWriter(org.openstreetmap.atlas.streaming.writers.SafeBufferedWriter) Taggable(org.openstreetmap.atlas.tags.Taggable) List(java.util.List) InputStreamResource(org.openstreetmap.atlas.streaming.resource.InputStreamResource) Rectangle(org.openstreetmap.atlas.geography.Rectangle) StringList(org.openstreetmap.atlas.utilities.collections.StringList) Time(org.openstreetmap.atlas.utilities.time.Time) HttpHost(org.apache.http.HttpHost) Envelope(org.locationtech.jts.geom.Envelope) STRtree(org.locationtech.jts.index.strtree.STRtree) CountryShard(org.openstreetmap.atlas.geography.sharding.CountryShard) StringList(org.openstreetmap.atlas.utilities.collections.StringList) Rectangle(org.openstreetmap.atlas.geography.Rectangle) SafeBufferedWriter(org.openstreetmap.atlas.streaming.writers.SafeBufferedWriter) CoreException(org.openstreetmap.atlas.exception.CoreException) Clip(org.openstreetmap.atlas.geography.clipping.Clip) CoreException(org.openstreetmap.atlas.exception.CoreException) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) STRtree(org.locationtech.jts.index.strtree.STRtree) Location(org.openstreetmap.atlas.geography.Location)

Example 2 with MultiPolygon

use of org.openstreetmap.atlas.geography.MultiPolygon in project atlas by osmlab.

the class AtlasDebugTool method onRun.

@Override
protected int onRun(final CommandMap command) {
    final File pbf = (File) command.get(PBF);
    final File atlasFile = (File) command.get(ATLAS);
    final File geojson = (File) command.get(GEOJSON);
    final File text = (File) command.get(TEXT);
    final java.io.File boundaryFile = (java.io.File) command.get(BOUNDARY);
    final String country = (String) command.get(COUNTRY);
    final Rectangle bound = (Rectangle) command.get(BOUND);
    final MultiPolygon inputMultipolygon = (MultiPolygon) command.get(MULTIPOLYGON);
    @SuppressWarnings("unchecked") final List<Location> startEndRoute = (List<Location>) command.get(ROUTE);
    Atlas atlas;
    if (pbf != null && pbf.exists()) {
        final AtlasLoadingOption option;
        MultiPolygon multiPolygon = MultiPolygon.forPolygon(Rectangle.MAXIMUM);
        if (boundaryFile != null) {
            final CountryBoundaryMap boundaryMap = CountryBoundaryMap.fromShapeFile(boundaryFile);
            option = AtlasLoadingOption.createOptionWithAllEnabled(boundaryMap);
            if (country != null) {
                if (new CountryListTwoWayStringConverter().convert(country).size() == 1) {
                    multiPolygon = boundaryMap.countryBoundary(country).get(0).getBoundary();
                }
                option.setCountryCode(country);
            }
        } else {
            option = AtlasLoadingOption.createOptionWithNoSlicing();
        }
        if (bound != null) {
            multiPolygon = MultiPolygon.forPolygon(bound);
        }
        if (inputMultipolygon != null) {
            multiPolygon = inputMultipolygon;
        }
        atlas = new RawAtlasGenerator(pbf, option, multiPolygon).build();
        if (option.isCountrySlicing()) {
            atlas = new RawAtlasSlicer(option, atlas).slice();
        }
        atlas = new WaySectionProcessor(atlas, option).run();
        atlas.save(atlasFile);
    } else if (atlasFile != null && atlasFile.exists()) {
        atlas = new AtlasResourceLoader().load(atlasFile);
    } else {
        logger.error("Must have at least one source, -pbf or -atlas");
        atlas = null;
        System.exit(1);
    }
    logger.info("Loaded {}", atlas.summary());
    if (geojson != null) {
        atlas.saveAsGeoJson(geojson);
    }
    if (text != null) {
        atlas.saveAsText(text);
    }
    if (startEndRoute != null) {
        logger.info("Route between {} and {} = {}", startEndRoute.get(0), startEndRoute.get(1), AStarRouter.dijkstra(atlas, Distance.TEN_MILES).route(startEndRoute.get(0), startEndRoute.get(1)));
    }
    return 0;
}
Also used : Atlas(org.openstreetmap.atlas.geography.atlas.Atlas) WaySectionProcessor(org.openstreetmap.atlas.geography.atlas.raw.sectioning.WaySectionProcessor) Rectangle(org.openstreetmap.atlas.geography.Rectangle) RawAtlasGenerator(org.openstreetmap.atlas.geography.atlas.raw.creation.RawAtlasGenerator) AtlasResourceLoader(org.openstreetmap.atlas.geography.atlas.AtlasResourceLoader) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) ArrayList(java.util.ArrayList) List(java.util.List) StringList(org.openstreetmap.atlas.utilities.collections.StringList) AtlasLoadingOption(org.openstreetmap.atlas.geography.atlas.pbf.AtlasLoadingOption) CountryBoundaryMap(org.openstreetmap.atlas.geography.boundary.CountryBoundaryMap) CountryListTwoWayStringConverter(org.openstreetmap.atlas.geography.boundary.converters.CountryListTwoWayStringConverter) RawAtlasSlicer(org.openstreetmap.atlas.geography.atlas.raw.slicing.RawAtlasSlicer) File(org.openstreetmap.atlas.streaming.resource.File) Location(org.openstreetmap.atlas.geography.Location)

Example 3 with MultiPolygon

use of org.openstreetmap.atlas.geography.MultiPolygon in project atlas by osmlab.

the class RelationOrAreaToMultiPolygonConverter method convert.

@Override
public MultiPolygon convert(final AtlasEntity entity) {
    if (entity instanceof Relation) {
        final Relation relation = (Relation) entity;
        if (relation.isMultiPolygon()) {
            // Loop through the relation members, extract the inners and outers, and create the
            // outline.
            final MultiMap<Polygon, Polygon> outerToInners = new MultiMap<>();
            for (final Polygon outer : OUTER_CONVERTER.convert(relation)) {
                outerToInners.put(outer, new ArrayList<>());
            }
            if (outerToInners.isEmpty()) {
                throw new CoreException("Unable to find outer polygon.");
            }
            for (final Polygon inner : INNER_CONVERTER.convert(relation)) {
                boolean added = false;
                for (final Polygon outer : outerToInners.keySet()) {
                    if (outer.overlaps(inner) && !inner.fullyGeometricallyEncloses(outer)) {
                        outerToInners.add(outer, inner);
                        added = true;
                        break;
                    }
                }
                if (!added) {
                    throw new CoreException("Malformed MultiPolygon: inner has no outer host: {}", inner);
                }
            }
            return new MultiPolygon(outerToInners);
        } else {
            throw new CoreException("This is not a multipolygon relation");
        }
    } else if (entity instanceof Area) {
        return MultiPolygon.forPolygon(((Area) entity).asPolygon());
    } else {
        throw new CoreException("The outline is not an area nor a relation: {}", entity);
    }
}
Also used : MultiMap(org.openstreetmap.atlas.utilities.maps.MultiMap) Relation(org.openstreetmap.atlas.geography.atlas.items.Relation) Area(org.openstreetmap.atlas.geography.atlas.items.Area) CoreException(org.openstreetmap.atlas.exception.CoreException) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) Polygon(org.openstreetmap.atlas.geography.Polygon)

Example 4 with MultiPolygon

use of org.openstreetmap.atlas.geography.MultiPolygon in project atlas by osmlab.

the class ComplexBoundary method removeOuter.

public void removeOuter(final Polygon outerToRemove) {
    final MultiMap<Polygon, Polygon> outersToInners = new MultiMap<>();
    this.outline.outers().forEach(outer -> {
        final List<Polygon> innersForThisOuter = this.outline.innersOf(outer);
        outersToInners.put(outer, innersForThisOuter);
    });
    outersToInners.remove(outerToRemove);
    setOutline(new MultiPolygon(outersToInners));
}
Also used : MultiMap(org.openstreetmap.atlas.utilities.maps.MultiMap) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) Polygon(org.openstreetmap.atlas.geography.Polygon)

Example 5 with MultiPolygon

use of org.openstreetmap.atlas.geography.MultiPolygon in project atlas by osmlab.

the class RawAtlasSlicer method slicePolygonGeometry.

/**
 * Take a polygon and find its slices, while also checking for validity and geometric
 * consistency (i.e. only Polygonal results)
 *
 * @param identifier
 *            the OSM identifier for the Line being sliced
 * @param polygon
 *            The Polygon being sliced
 * @param intersectingBoundaryPolygons
 *            All intersecting country boundary polygons
 * @return A SortedMap of country codes to the portions of the Polygon inside those country
 *         boundary polygons
 */
private SortedMap<String, Set<org.locationtech.jts.geom.Polygon>> slicePolygonGeometry(final long identifier, final org.locationtech.jts.geom.Polygon polygon, final Set<org.locationtech.jts.geom.Polygon> intersectingBoundaryPolygon) {
    final Map<String, Set<Geometry>> currentResults = sliceGeometry(polygon, intersectingBoundaryPolygon);
    final SortedMap<String, Set<org.locationtech.jts.geom.Polygon>> results = new TreeMap<>();
    for (final Map.Entry<String, Set<Geometry>> entry : currentResults.entrySet()) {
        final String countryCode = entry.getKey();
        final Set<org.locationtech.jts.geom.Polygon> slicedPolygons = new HashSet<>();
        entry.getValue().forEach(geometry -> {
            if (geometry instanceof org.locationtech.jts.geom.Polygon) {
                // the log as an error so it should be easy to find
                if (((org.locationtech.jts.geom.Polygon) geometry).getNumInteriorRing() > 0) {
                    throw new CoreException("Line {} for Atlas {} had multipolygon geometry {}!", identifier, this.shardOrAtlasName, geometry.toText());
                } else {
                    slicedPolygons.add((org.locationtech.jts.geom.Polygon) geometry);
                }
            }
        });
        results.put(countryCode, slicedPolygons);
    }
    return results;
}
Also used : SortedSet(java.util.SortedSet) Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) LineString(org.locationtech.jts.geom.LineString) TreeMap(java.util.TreeMap) CoreException(org.openstreetmap.atlas.exception.CoreException) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) Polygon(org.openstreetmap.atlas.geography.Polygon) Map(java.util.Map) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) CountryBoundaryMap(org.openstreetmap.atlas.geography.boundary.CountryBoundaryMap) TreeMap(java.util.TreeMap) HashSet(java.util.HashSet)

Aggregations

MultiPolygon (org.openstreetmap.atlas.geography.MultiPolygon)78 Polygon (org.openstreetmap.atlas.geography.Polygon)40 Test (org.junit.Test)35 ArrayList (java.util.ArrayList)19 CoreException (org.openstreetmap.atlas.exception.CoreException)19 MultiMap (org.openstreetmap.atlas.utilities.maps.MultiMap)16 HashMap (java.util.HashMap)14 HashSet (java.util.HashSet)14 PolyLine (org.openstreetmap.atlas.geography.PolyLine)13 Atlas (org.openstreetmap.atlas.geography.atlas.Atlas)13 CountryBoundaryMap (org.openstreetmap.atlas.geography.boundary.CountryBoundaryMap)11 List (java.util.List)10 Rectangle (org.openstreetmap.atlas.geography.Rectangle)9 Map (java.util.Map)8 Location (org.openstreetmap.atlas.geography.Location)8 Set (java.util.Set)7 Geometry (org.locationtech.jts.geom.Geometry)7 TreeSet (java.util.TreeSet)6 Collectors (java.util.stream.Collectors)6 LineString (org.locationtech.jts.geom.LineString)6