List of usage examples for org.apache.commons.math3.geometry.partitioning RegionFactory intersection
public Region<S> intersection(final Region<S> region1, final Region<S> region2)
From source file:org.orekit.models.earth.tessellation.EllipsoidTessellator.java
/** Tessellate a zone of interest into tiles. * <p>/*from w w w . j a v a 2s .co m*/ * The created tiles will completely cover the zone of interest. * </p> * <p> * The distance between a vertex at a tile corner and the vertex at the same corner * in the next vertex are computed by subtracting the overlap width (resp. overlap length) * from the full width (resp. full length). If for example the full width is specified to * be 55 km and the overlap in width is specified to be +5 km, successive tiles would span * as follows: * </p> * <ul> * <li>tile 1 covering from 0 km to 55 km</li> * <li>tile 2 covering from 50 km to 105 km</li> * <li>tile 3 covering from 100 km to 155 km</li> * <li>...</li> * </ul> * <p> * In order to achieve the same 50 km step but using a 5 km gap instead of an overlap, one would * need to specify the full width to be 45 km and the overlap to be -5 km. With these settings, * successive tiles would span as follows: * </p> * <ul> * <li>tile 1 covering from 0 km to 45 km</li> * <li>tile 2 covering from 50 km to 95 km</li> * <li>tile 3 covering from 100 km to 155 km</li> * <li>...</li> * </ul> * @param zone zone of interest to tessellate * @param fullWidth full tiles width as a distance on surface, including overlap (in meters) * @param fullLength full tiles length as a distance on surface, including overlap (in meters) * @param widthOverlap overlap between adjacent tiles (in meters), if negative the tiles * will have a gap between each other instead of an overlap * @param lengthOverlap overlap between adjacent tiles (in meters), if negative the tiles * will have a gap between each other instead of an overlap * @param truncateLastWidth if true, the first tiles strip will be started as close as * possible to the zone of interest, and the last tiles strip will have its width reduced * to also remain close to the zone of interest; if false all tiles strip will have the * same {@code fullWidth} and they will be balanced around zone of interest * @param truncateLastLength if true, the first tile in each strip will be started as close as * possible to the zone of interest, and the last tile in each strip will have its length reduced * to also remain close to the zone of interest; if false all tiles in each strip will have the * same {@code fullLength} and they will be balanced around zone of interest * @return a list of lists of tiles covering the zone of interest, * each sub-list corresponding to a part not connected to the other * parts (for example for islands) * @exception OrekitException if the zone cannot be tessellated */ public List<List<Tile>> tessellate(final SphericalPolygonsSet zone, final double fullWidth, final double fullLength, final double widthOverlap, final double lengthOverlap, final boolean truncateLastWidth, final boolean truncateLastLength) throws OrekitException { final double splitWidth = (fullWidth - widthOverlap) / quantization; final double splitLength = (fullLength - lengthOverlap) / quantization; final Map<Mesh, List<Tile>> map = new IdentityHashMap<Mesh, List<Tile>>(); final RegionFactory<Sphere2D> factory = new RegionFactory<Sphere2D>(); SphericalPolygonsSet remaining = (SphericalPolygonsSet) zone.copySelf(); S2Point inside = getInsidePoint(remaining); while (inside != null) { // find a mesh covering at least one connected part of the zone final List<Mesh.Node> mergingSeeds = new ArrayList<Mesh.Node>(); Mesh mesh = new Mesh(ellipsoid, zone, aiming, splitLength, splitWidth, inside); mergingSeeds.add(mesh.getNode(0, 0)); List<Tile> tiles = null; while (!mergingSeeds.isEmpty()) { // expand the mesh around the seed neighborExpandMesh(mesh, mergingSeeds, zone); // extract the tiles from the mesh // this further expands the mesh so tiles dimensions are multiples of quantization, // hence it must be performed here before checking meshes independence tiles = extractTiles(mesh, zone, lengthOverlap, widthOverlap, truncateLastWidth, truncateLastLength); // check the mesh is independent from existing meshes mergingSeeds.clear(); for (final Map.Entry<Mesh, List<Tile>> entry : map.entrySet()) { if (!factory.intersection(mesh.getCoverage(), entry.getKey().getCoverage()).isEmpty()) { // the meshes are not independent, they intersect each other! // merge the two meshes together mesh = mergeMeshes(mesh, entry.getKey(), mergingSeeds); map.remove(entry.getKey()); break; } } } // remove the part of the zone covered by the mesh remaining = (SphericalPolygonsSet) factory.difference(remaining, mesh.getCoverage()); inside = getInsidePoint(remaining); map.put(mesh, tiles); } // concatenate the lists from the independent meshes final List<List<Tile>> tilesLists = new ArrayList<List<Tile>>(map.size()); for (final Map.Entry<Mesh, List<Tile>> entry : map.entrySet()) { tilesLists.add(entry.getValue()); } return tilesLists; }
From source file:org.orekit.models.earth.tessellation.EllipsoidTessellator.java
/** Sample a zone of interest into a grid sample of {@link GeodeticPoint geodetic points}. * <p>/* w w w . j a va 2 s. co m*/ * The created points will be entirely within the zone of interest. * </p> * @param zone zone of interest to sample * @param width grid sample cells width as a distance on surface (in meters) * @param length grid sample cells length as a distance on surface (in meters) * @return a list of lists of points sampling the zone of interest, * each sub-list corresponding to a part not connected to the other * parts (for example for islands) * @exception OrekitException if the zone cannot be sampled */ public List<List<GeodeticPoint>> sample(final SphericalPolygonsSet zone, final double width, final double length) throws OrekitException { final double splitWidth = width / quantization; final double splitLength = length / quantization; final Map<Mesh, List<GeodeticPoint>> map = new IdentityHashMap<Mesh, List<GeodeticPoint>>(); final RegionFactory<Sphere2D> factory = new RegionFactory<Sphere2D>(); SphericalPolygonsSet remaining = (SphericalPolygonsSet) zone.copySelf(); S2Point inside = getInsidePoint(remaining); while (inside != null) { // find a mesh covering at least one connected part of the zone final List<Mesh.Node> mergingSeeds = new ArrayList<Mesh.Node>(); Mesh mesh = new Mesh(ellipsoid, zone, aiming, splitLength, splitWidth, inside); mergingSeeds.add(mesh.getNode(0, 0)); List<GeodeticPoint> sample = null; while (!mergingSeeds.isEmpty()) { // expand the mesh around the seed neighborExpandMesh(mesh, mergingSeeds, zone); // extract the sample from the mesh // this further expands the mesh so sample cells dimensions are multiples of quantization, // hence it must be performed here before checking meshes independence sample = extractSample(mesh, zone); // check the mesh is independent from existing meshes mergingSeeds.clear(); for (final Map.Entry<Mesh, List<GeodeticPoint>> entry : map.entrySet()) { if (!factory.intersection(mesh.getCoverage(), entry.getKey().getCoverage()).isEmpty()) { // the meshes are not independent, they intersect each other! // merge the two meshes together mesh = mergeMeshes(mesh, entry.getKey(), mergingSeeds); map.remove(entry.getKey()); break; } } } // remove the part of the zone covered by the mesh remaining = (SphericalPolygonsSet) factory.difference(remaining, mesh.getCoverage()); inside = getInsidePoint(remaining); map.put(mesh, sample); } // concatenate the lists from the independent meshes final List<List<GeodeticPoint>> sampleLists = new ArrayList<List<GeodeticPoint>>(map.size()); for (final Map.Entry<Mesh, List<GeodeticPoint>> entry : map.entrySet()) { sampleLists.add(entry.getValue()); } return sampleLists; }