kopia lustrzana https://github.com/JOSM/MapWithAI
MapWithAIInfo: Fix an issue where users would be unable to file bug reports
Signed-off-by: Taylor Smock <tsmock@fb.com>pull/1/head
rodzic
52724d0ab7
commit
42aec40b25
|
@ -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()));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue