MapWithAIInfo: Fix an issue where users would be unable to file bug reports

Signed-off-by: Taylor Smock <tsmock@fb.com>
pull/1/head
Taylor Smock 2022-05-12 12:21:55 -06:00
rodzic 52724d0ab7
commit 42aec40b25
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 625F6A74A3E4311A
4 zmienionych plików z 133 dodań i 60 usunięć

Wyświetl plik

@ -0,0 +1,106 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.data.mapwithai;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.imagery.ImageryInfo;
import org.openstreetmap.josm.data.imagery.Shape;
import org.openstreetmap.josm.data.osm.BBox;
import org.openstreetmap.josm.data.sources.SourceBounds;
import org.openstreetmap.josm.tools.DefaultGeoProperty;
import org.openstreetmap.josm.tools.GeoPropertyIndex;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.Territories;
/**
* Get country data for use in info classes
*/
public final class CountryUtils {
private CountryUtils() {
/* Hide constructor */
}
/**
* Get the country shape
*
* @param country The country to get the shape for
* @return The (optional) bounds (may be empty if no country matched)
*/
public static Optional<ImageryInfo.ImageryBounds> getCountryShape(String country) {
GeoPropertyIndex<Boolean> geoPropertyIndex = Territories.getGeoPropertyIndex(country);
if (geoPropertyIndex.getGeoProperty() instanceof DefaultGeoProperty) {
DefaultGeoProperty prop = (DefaultGeoProperty) geoPropertyIndex.getGeoProperty();
Rectangle2D areaBounds = prop.getArea().getBounds2D();
ImageryInfo.ImageryBounds tmp = new ImageryInfo.ImageryBounds(bboxToBoundsString(
new BBox(areaBounds.getMinX(), areaBounds.getMinY(), areaBounds.getMaxX(), areaBounds.getMaxY())),
",");
areaToShapes(prop.getArea()).forEach(tmp::addShape);
return Optional.of(tmp);
}
return Optional.empty();
}
/**
* Get the country for a given shape
*
* @param shape The shape to get a country for
* @return The country, if found
*/
public static Optional<String> shapeToCountry(Shape shape) {
for (String country : Territories.getKnownIso3166Codes()) {
List<Shape> shapes = getCountryShape(country).map(SourceBounds::getShapes)
.orElseGet(Collections::emptyList);
for (Shape checkShape : shapes) {
if (Objects.equals(shape, checkShape)) {
return Optional.of(country);
}
}
}
return Optional.empty();
}
private static Collection<Shape> areaToShapes(java.awt.Shape shape) {
PathIterator iterator = shape.getPathIterator(new AffineTransform());
Shape defaultShape = new Shape();
Collection<Shape> shapes = new ArrayList<>();
float[] moveTo = null;
float[] coords = new float[6];
while (!iterator.isDone()) {
int type = iterator.currentSegment(coords);
if (type == PathIterator.SEG_MOVETO || type == PathIterator.SEG_LINETO) {
if (type == PathIterator.SEG_MOVETO) {
moveTo = coords;
}
defaultShape.addPoint(Float.toString(coords[1]), Float.toString(coords[0]));
} else if (type == PathIterator.SEG_CLOSE && moveTo != null) {
defaultShape.addPoint(Float.toString(moveTo[1]), Float.toString(moveTo[0]));
shapes.add(defaultShape);
defaultShape = new Shape();
} else {
Logging.error(tr("No implementation for converting a segment of type {0} to coordinates", type));
}
iterator.next();
}
if (!defaultShape.getPoints().isEmpty()) {
shapes.add(defaultShape);
}
return shapes;
}
private static String bboxToBoundsString(BBox bbox) {
return String.join(",", LatLon.cDdFormatter.format(bbox.getBottomRightLat()),
LatLon.cDdFormatter.format(bbox.getTopLeftLon()), LatLon.cDdFormatter.format(bbox.getTopLeftLat()),
LatLon.cDdFormatter.format(bbox.getBottomRightLon()));
}
}

Wyświetl plik

@ -18,6 +18,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -27,6 +28,7 @@ import org.openstreetmap.josm.data.imagery.ImageryInfo;
import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryBounds;
import org.openstreetmap.josm.data.imagery.Shape;
import org.openstreetmap.josm.data.preferences.BooleanProperty;
import org.openstreetmap.josm.data.sources.SourceBounds;
import org.openstreetmap.josm.data.sources.SourceInfo;
import org.openstreetmap.josm.data.sources.SourcePreferenceEntry;
import org.openstreetmap.josm.tools.CheckParameterUtil;
@ -116,6 +118,22 @@ public class MapWithAIInfo extends
.collect(Collectors.joining(";"));
}
alreadyConflatedKey = i.alreadyConflatedKey;
if (i.bounds != null && this.shapes != null && this.shapes.length() > Byte.MAX_VALUE) {
List<String> parts = new ArrayList<>(i.bounds.getShapes().size());
for (Shape s : i.bounds.getShapes()) {
Optional<String> country = CountryUtils.shapeToCountry(s);
if (country.isPresent()) {
if (!parts.contains(country.get())) {
parts.add(country.get());
}
} else {
parts.add(s.encodeAsString(","));
}
}
if (!parts.isEmpty()) {
shapes = String.join(";", parts);
}
}
}
@Override
@ -211,7 +229,12 @@ public class MapWithAIInfo extends
if (e.shapes != null) {
try {
for (String s : e.shapes.split(";", -1)) {
bounds.addShape(new Shape(s, ","));
if (s.matches("[\\d,]+")) {
bounds.addShape(new Shape(s, ","));
} else {
CountryUtils.getCountryShape(s).map(SourceBounds::getShapes)
.orElseThrow(IllegalStateException::new).forEach(bounds::addShape);
}
}
} catch (IllegalArgumentException ex) {
Logging.warn(ex);

Wyświetl plik

@ -35,7 +35,6 @@ import org.openstreetmap.josm.gui.PleaseWaitRunnable;
import org.openstreetmap.josm.io.CachedFile;
import org.openstreetmap.josm.io.NetworkManager;
import org.openstreetmap.josm.io.imagery.ImageryReader;
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIDataUtils;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo.MapWithAIPreferenceEntry;
import org.openstreetmap.josm.plugins.mapwithai.io.mapwithai.ESRISourceReader;
import org.openstreetmap.josm.plugins.mapwithai.io.mapwithai.MapWithAISourceReader;
@ -193,7 +192,7 @@ public class MapWithAILayerInfo {
if (System.getSecurityManager() != null) {
Logging.trace("MapWithAI loaded: {0}", ESRISourceReader.SOURCE_CACHE.getClass());
}
loadDefaults(false, MapWithAIDataUtils.getForkJoinPool(), fastFail, listener);
loadDefaults(false, MainApplication.worker, fastFail, listener);
}
/**

Wyświetl plik

@ -1,19 +1,13 @@
// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.mapwithai.io.mapwithai;
import static org.openstreetmap.josm.tools.I18n.tr;
import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonString;
import javax.json.JsonValue;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -21,16 +15,12 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.imagery.ImageryInfo;
import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryBounds;
import org.openstreetmap.josm.data.imagery.Shape;
import org.openstreetmap.josm.data.osm.BBox;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.CountryUtils;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAICategory;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIInfo;
import org.openstreetmap.josm.plugins.mapwithai.data.mapwithai.MapWithAIType;
import org.openstreetmap.josm.tools.DefaultGeoProperty;
import org.openstreetmap.josm.tools.GeoPropertyIndex;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.Territories;
@ -43,9 +33,6 @@ import org.openstreetmap.josm.tools.Territories;
* source</a>.
*/
public class MapWithAISourceReader extends CommonSourceReader<List<MapWithAIInfo>> implements Closeable {
private static final int COORD_ARRAY_SIZE = 6;
/**
* Constructs a {@code MapWithAISourceReader} from a given filename, URL or
* internal resource.
@ -143,15 +130,7 @@ public class MapWithAISourceReader extends CommonSourceReader<List<MapWithAIInfo
List<ImageryBounds> bounds = new ArrayList<>();
for (Map.Entry<String, JsonValue> country : countries.asJsonObject().entrySet()) {
if (codes.contains(country.getKey())) {
GeoPropertyIndex<Boolean> geoPropertyIndex = Territories.getGeoPropertyIndex(country.getKey());
if (geoPropertyIndex.getGeoProperty() instanceof DefaultGeoProperty) {
DefaultGeoProperty prop = (DefaultGeoProperty) geoPropertyIndex.getGeoProperty();
Rectangle2D areaBounds = prop.getArea().getBounds2D();
ImageryBounds tmp = new ImageryBounds(bboxToBoundsString(new BBox(areaBounds.getMinX(),
areaBounds.getMinY(), areaBounds.getMaxX(), areaBounds.getMaxY())), ",");
areaToShapes(prop.getArea()).forEach(tmp::addShape);
bounds.add(tmp);
}
CountryUtils.getCountryShape(country.getKey()).ifPresent(bounds::add);
}
}
return bounds;
@ -162,38 +141,4 @@ public class MapWithAISourceReader extends CommonSourceReader<List<MapWithAIInfo
}
return new ArrayList<>();
}
private static Collection<Shape> areaToShapes(java.awt.Shape shape) {
PathIterator iterator = shape.getPathIterator(new AffineTransform());
Shape defaultShape = new Shape();
Collection<Shape> shapes = new ArrayList<>();
float[] moveTo = null;
while (!iterator.isDone()) {
float[] coords = new float[COORD_ARRAY_SIZE];
int type = iterator.currentSegment(coords);
if (type == PathIterator.SEG_MOVETO || type == PathIterator.SEG_LINETO) {
if (type == PathIterator.SEG_MOVETO) {
moveTo = coords;
}
defaultShape.addPoint(Float.toString(coords[1]), Float.toString(coords[0]));
} else if (type == PathIterator.SEG_CLOSE && moveTo != null) {
defaultShape.addPoint(Float.toString(moveTo[1]), Float.toString(moveTo[0]));
shapes.add(defaultShape);
defaultShape = new Shape();
} else {
Logging.error(tr("No implementation for converting a segment of type {0} to coordinates", type));
}
iterator.next();
}
if (!defaultShape.getPoints().isEmpty()) {
shapes.add(defaultShape);
}
return shapes;
}
private static String bboxToBoundsString(BBox bbox) {
return String.join(",", LatLon.cDdFormatter.format(bbox.getBottomRightLat()),
LatLon.cDdFormatter.format(bbox.getTopLeftLon()), LatLon.cDdFormatter.format(bbox.getTopLeftLat()),
LatLon.cDdFormatter.format(bbox.getBottomRightLon()));
}
}