kopia lustrzana https://github.com/JOSM/MapWithAI
Give indications if there may be data available in the region
Update dependencies, slight bump on minimum JOSM version (15229 -> 15233) Signed-off-by: Taylor Smock <taylor.smock@kaart.com>pull/1/head
rodzic
f569da2772
commit
d48ef81aae
|
@ -11,10 +11,10 @@ plugins {
|
|||
id "jacoco"
|
||||
id "maven-publish"
|
||||
id "pmd"
|
||||
id "com.github.ben-manes.versions" version "0.25.0"
|
||||
id "com.github.ben-manes.versions" version "0.26.0"
|
||||
id "com.github.spotbugs" version "2.0.0"
|
||||
id "org.openstreetmap.josm" version "0.6.1"
|
||||
id "net.ltgt.errorprone" version "0.8.1"
|
||||
id "org.openstreetmap.josm" version "0.6.4"
|
||||
id "net.ltgt.errorprone" version "1.0.0"
|
||||
//id 'de.aaschmid.cpd' version '2.0'
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ def versions = [
|
|||
junit: "5.5.2",
|
||||
pmd: "6.6.0",
|
||||
spotbugs: "3.1.12",
|
||||
wiremock: "2.24.1",
|
||||
wiremock: "2.25.0",
|
||||
]
|
||||
|
||||
repositories {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# The minimum JOSM version this plugin is compatible with (can be any numeric version)
|
||||
plugin.main.version = 15229
|
||||
plugin.main.version = 15233
|
||||
# The JOSM version this plugin is currently compiled against
|
||||
# Please make sure this version is available at https://josm.openstreetmap.de/download
|
||||
# The special values "latest" and "tested" are also possible here, but not recommended.
|
||||
plugin.compile.version = 15229
|
||||
plugin.compile.version = 15233
|
||||
plugin.canloadatruntime = true
|
||||
plugin.author = Taylor Smock <incoming+smocktaylor/rapid@incoming.gitlab.com>
|
||||
plugin.class = org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin
|
||||
|
|
|
@ -5,11 +5,21 @@ import static org.openstreetmap.josm.tools.I18n.tr;
|
|||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.openstreetmap.josm.actions.JosmAction;
|
||||
import org.openstreetmap.josm.data.Bounds;
|
||||
import org.openstreetmap.josm.gui.Notification;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin;
|
||||
import org.openstreetmap.josm.tools.Shortcut;
|
||||
|
||||
|
||||
public class MapWithAIAction extends JosmAction {
|
||||
/** UID */
|
||||
private static final long serialVersionUID = 8886705479253246588L;
|
||||
|
@ -23,11 +33,45 @@ public class MapWithAIAction extends JosmAction {
|
|||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
MapWithAIDataUtils.getMapWithAIData(MapWithAIDataUtils.getLayer(true));
|
||||
if (isEnabled()) {
|
||||
MapWithAIDataUtils.getMapWithAIData(MapWithAIDataUtils.getLayer(true));
|
||||
createMessageDialog();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateEnabledState() {
|
||||
setEnabled(getLayerManager().getEditDataSet() != null);
|
||||
}
|
||||
|
||||
public void createMessageDialog() {
|
||||
final MapWithAILayer layer = MapWithAIDataUtils.getLayer(false);
|
||||
if (layer != null) {
|
||||
final Notification notification = new Notification();
|
||||
final List<Bounds> bounds = layer.getDataSet().getDataSourceBounds();
|
||||
final StringBuilder message = new StringBuilder();
|
||||
message.append(MapWithAIPlugin.NAME);
|
||||
message.append(": ");
|
||||
MapWithAIAvailability availability = MapWithAIAvailability.getInstance();
|
||||
Map<String, Boolean> availableTypes = new TreeMap<>();
|
||||
for (final Bounds bound : bounds) {
|
||||
availability.getDataTypes(bound.getCenter())
|
||||
.forEach((type, available) -> availableTypes.merge(type, available, Boolean::logicalOr));
|
||||
}
|
||||
List<String> types = availableTypes.entrySet().stream().filter(Entry::getValue)
|
||||
.map(entry -> MapWithAIAvailability.getPossibleDataTypesAndMessages().get(entry.getKey()))
|
||||
.collect(Collectors.toList());
|
||||
if (types.isEmpty()) {
|
||||
message.append(tr("No data available"));
|
||||
} else {
|
||||
message.append("Data available: ");
|
||||
message.append(String.join(", ", types));
|
||||
}
|
||||
|
||||
notification.setContent(message.toString());
|
||||
notification.setDuration(Notification.TIME_LONG);
|
||||
notification.setIcon(JOptionPane.INFORMATION_MESSAGE);
|
||||
notification.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.mapwithai.backend;
|
||||
|
||||
import static org.openstreetmap.josm.tools.I18n.tr;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.json.Json;
|
||||
import javax.json.JsonArray;
|
||||
import javax.json.JsonObject;
|
||||
import javax.json.JsonValue;
|
||||
import javax.json.stream.JsonParser;
|
||||
|
||||
import org.openstreetmap.josm.data.coor.LatLon;
|
||||
import org.openstreetmap.josm.data.osm.BBox;
|
||||
import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
||||
import org.openstreetmap.josm.io.CachedFile;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.MapWithAIPlugin;
|
||||
import org.openstreetmap.josm.tools.Logging;
|
||||
import org.openstreetmap.josm.tools.Territories;
|
||||
|
||||
public class MapWithAIAvailability {
|
||||
private static final String RAPID_RELEASES = "https://github.com/facebookmicrosites/Open-Mapping-At-Facebook/raw/master/data/rapid_realeases.geojson";
|
||||
private static MapWithAIAvailability instance = null;
|
||||
private static final Map<String, Map<String, Boolean>> COUNTRIES = new HashMap<>();
|
||||
private static final Map<String, String> POSSIBLE_DATA_POINTS = new TreeMap<>();
|
||||
private static final Map<String, String> COUNTRY_NAME_FIX = new HashMap<>();
|
||||
static {
|
||||
COUNTRY_NAME_FIX.put("Egypt", "Egypt, Arab Rep.");
|
||||
COUNTRY_NAME_FIX.put("Dem. Rep. Congo", "Congo, Dem. Rep.");
|
||||
POSSIBLE_DATA_POINTS.put("roads", "RapiD roads available");
|
||||
POSSIBLE_DATA_POINTS.put("buildings", "MS buildings available");
|
||||
}
|
||||
|
||||
private MapWithAIAvailability() {
|
||||
try (CachedFile rapidReleases = new CachedFile(RAPID_RELEASES);
|
||||
JsonParser parser = Json.createParser(rapidReleases.getContentReader())) {
|
||||
if (parser.hasNext()) {
|
||||
JsonParser.Event event = parser.next();
|
||||
if (JsonParser.Event.START_OBJECT.equals(event)) {
|
||||
Stream<Entry<String, JsonValue>> entries = parser.getObjectStream();
|
||||
Optional<Entry<String, JsonValue>> objects = entries.filter(entry -> "objects".equals(entry.getKey()))
|
||||
.findFirst();
|
||||
if (objects.isPresent()) {
|
||||
JsonObject value = objects.get().getValue().asJsonObject();
|
||||
JsonObject centroid = value.getJsonObject("rapid_releases_1011_centroid");
|
||||
JsonArray countries = centroid.getJsonArray("geometries");
|
||||
parseForCountries(countries);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Logging.debug(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the unique instance
|
||||
*/
|
||||
public static MapWithAIAvailability getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new MapWithAIAvailability();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static void parseForCountries(JsonArray countries) {
|
||||
for (int i = 0; i < countries.size(); i++) {
|
||||
JsonObject country = countries.getJsonObject(i).getJsonObject("properties");
|
||||
String countryName = cornerCaseNames(country.getString("Country"));
|
||||
Optional<OsmPrimitive> realCountry = Territories.getDataSet().allPrimitives().parallelStream()
|
||||
.filter(primitive -> countryName.equalsIgnoreCase(primitive.get("name:en")))
|
||||
.findFirst();
|
||||
if (realCountry.isPresent()) {
|
||||
String key = realCountry.get().get("ISO3166-1:alpha2");
|
||||
// We need to handle cases like Alaska more elegantly
|
||||
Map<String, Boolean> data = COUNTRIES.getOrDefault(key, new TreeMap<>());
|
||||
for (Entry<String, String> entry : POSSIBLE_DATA_POINTS.entrySet()) {
|
||||
boolean hasData = "yes".equals(country.getString(entry.getValue()));
|
||||
if (hasData || !data.containsKey(entry.getKey())) {
|
||||
data.put(entry.getKey(), hasData);
|
||||
}
|
||||
}
|
||||
COUNTRIES.put(key, data);
|
||||
} else {
|
||||
Logging.error(tr("{0}: We couldn''t find {1}", MapWithAIPlugin.NAME, countryName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String cornerCaseNames(String name) {
|
||||
if (COUNTRY_NAME_FIX.containsKey(name)) {
|
||||
name = COUNTRY_NAME_FIX.get(name);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bbox An area that may have data
|
||||
* @return True if one of the corners of the {@code bbox} is in a country with
|
||||
* available data.
|
||||
*/
|
||||
public boolean hasData(BBox bbox) {
|
||||
List<LatLon> corners = new ArrayList<>();
|
||||
corners.add(bbox.getBottomRight());
|
||||
corners.add(new LatLon(bbox.getBottomRightLat(), bbox.getTopLeftLon()));
|
||||
corners.add(bbox.getTopLeft());
|
||||
corners.add(new LatLon(bbox.getTopLeftLat(), bbox.getBottomRightLon()));
|
||||
return corners.parallelStream().anyMatch(this::hasData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param latLon A point that may have data from MapWithAI
|
||||
* @return true if it is in an ares with data from MapWithAI
|
||||
*/
|
||||
public boolean hasData(LatLon latLon) {
|
||||
boolean returnBoolean = false;
|
||||
for (Entry<String, Map<String, Boolean>> entry : COUNTRIES.entrySet()) {
|
||||
if (Territories.isIso3166Code(entry.getKey(), latLon)) {
|
||||
returnBoolean = entry.getValue().entrySet().parallelStream().anyMatch(Entry::getValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return returnBoolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data types that may be visible around a point
|
||||
*
|
||||
* @param latLon The point of interest
|
||||
* @return A map that may have available data types (or be empty)
|
||||
*/
|
||||
public Map<String, Boolean> getDataTypes(LatLon latLon) {
|
||||
return COUNTRIES.entrySet().parallelStream().filter(entry -> Territories.isIso3166Code(entry.getKey(), latLon))
|
||||
.map(Entry::getValue).findFirst().orElse(Collections.emptyMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A map of possible data types with their messages
|
||||
*/
|
||||
public static Map<String, String> getPossibleDataTypesAndMessages() {
|
||||
return POSSIBLE_DATA_POINTS;
|
||||
}
|
||||
}
|
|
@ -2,16 +2,12 @@
|
|||
package org.openstreetmap.josm.plugins.mapwithai.backend;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.openstreetmap.josm.data.Bounds;
|
||||
import org.openstreetmap.josm.data.DataSource;
|
||||
import org.openstreetmap.josm.data.osm.DataSet;
|
||||
import org.openstreetmap.josm.gui.MainApplication;
|
||||
import org.openstreetmap.josm.gui.layer.Layer;
|
||||
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIDataUtils;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAILayer;
|
||||
import org.openstreetmap.josm.testutils.JOSMTestRules;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
@ -21,46 +17,28 @@ public class MapWithAIActionTest {
|
|||
@SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
|
||||
public JOSMTestRules test = new JOSMTestRules().preferences().main().projection();
|
||||
|
||||
@Test
|
||||
public void testGetLayer() {
|
||||
Layer mapWithAILayer = MapWithAIDataUtils.getLayer(false);
|
||||
Assert.assertNull(mapWithAILayer);
|
||||
private MapWithAIAction action;
|
||||
|
||||
mapWithAILayer = MapWithAIDataUtils.getLayer(true);
|
||||
Assert.assertEquals(MapWithAILayer.class, mapWithAILayer.getClass());
|
||||
|
||||
Layer tMapWithAI = MapWithAIDataUtils.getLayer(false);
|
||||
Assert.assertSame(mapWithAILayer, tMapWithAI);
|
||||
|
||||
tMapWithAI = MapWithAIDataUtils.getLayer(true);
|
||||
Assert.assertSame(mapWithAILayer, tMapWithAI);
|
||||
@Before
|
||||
public void setUp() {
|
||||
action = new MapWithAIAction();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetData() {
|
||||
final MapWithAILayer mapWithAILayer = MapWithAIDataUtils.getLayer(true);
|
||||
final OsmDataLayer osm = new OsmDataLayer(new DataSet(), "test", null);
|
||||
MainApplication.getLayerManager().addLayer(osm);
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer, osm);
|
||||
public void testEnabled() {
|
||||
Assert.assertFalse(action.isEnabled());
|
||||
MainApplication.getLayerManager().addLayer(new OsmDataLayer(new DataSet(), "temporary", null));
|
||||
Assert.assertTrue(action.isEnabled());
|
||||
}
|
||||
|
||||
Assert.assertTrue(mapWithAILayer.getDataSet().getDataSourceBounds().isEmpty());
|
||||
@Test
|
||||
public void testDownload() {
|
||||
Assert.assertTrue(MainApplication.getLayerManager().getLayers().isEmpty());
|
||||
action.actionPerformed(null);
|
||||
Assert.assertTrue(MainApplication.getLayerManager().getLayers().isEmpty());
|
||||
|
||||
osm.getDataSet().addDataSource(new DataSource(new Bounds(0, 0, 0.001, 0.001), "random test"));
|
||||
|
||||
osm.lock();
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer);
|
||||
Assert.assertTrue(mapWithAILayer.getDataSet().getDataSourceBounds().isEmpty());
|
||||
osm.unlock();
|
||||
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer);
|
||||
Assert.assertFalse(mapWithAILayer.getDataSet().getDataSourceBounds().isEmpty());
|
||||
Assert.assertEquals(1, mapWithAILayer.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
|
||||
|
||||
osm.getDataSet().addDataSource(new DataSource(new Bounds(-0.001, -0.001, 0, 0), "random test"));
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer);
|
||||
Assert.assertEquals(2, mapWithAILayer.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
|
||||
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer);
|
||||
Assert.assertEquals(2, mapWithAILayer.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
|
||||
MainApplication.getLayerManager().addLayer(new OsmDataLayer(new DataSet(), "temporary", null));
|
||||
action.actionPerformed(null);
|
||||
Assert.assertEquals(1, MainApplication.getLayerManager().getLayersOfType(MapWithAILayer.class).size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// License: GPL. For details, see LICENSE file.
|
||||
package org.openstreetmap.josm.plugins.mapwithai.backend;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.openstreetmap.josm.data.coor.LatLon;
|
||||
import org.openstreetmap.josm.data.osm.BBox;
|
||||
import org.openstreetmap.josm.testutils.JOSMTestRules;
|
||||
import org.openstreetmap.josm.tools.Territories;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
||||
public class MapWithAIAvailabilityTest {
|
||||
private MapWithAIAvailability instance;
|
||||
|
||||
@Rule
|
||||
@SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
|
||||
public JOSMTestRules test = new JOSMTestRules().preferences().main().projection();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Territories.initialize();
|
||||
instance = MapWithAIAvailability.getInstance();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasDataBBox() {
|
||||
Assert.assertFalse(instance.hasData(new BBox(0, 0, 0.1, 0.1)));
|
||||
Assert.assertTrue(instance.hasData(new BBox(-99.9, 39.9, 100.1, 40.1)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasDataLatLon() {
|
||||
Assert.assertFalse(instance.hasData(new LatLon(0, 0)));
|
||||
Assert.assertTrue(instance.hasData(new LatLon(40, -100)));
|
||||
Assert.assertTrue(instance.hasData(new LatLon(45.424722, -75.695)));
|
||||
Assert.assertTrue(instance.hasData(new LatLon(19.433333, -99.133333)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testgetDataLatLon() {
|
||||
Assert.assertTrue(instance.getDataTypes(new LatLon(0, 0)).isEmpty());
|
||||
Assert.assertTrue(instance.getDataTypes(new LatLon(40, -100)).get("roads"));
|
||||
Assert.assertTrue(instance.getDataTypes(new LatLon(40, -100)).get("buildings"));
|
||||
Assert.assertFalse(instance.getDataTypes(new LatLon(45.424722, -75.695)).get("roads"));
|
||||
Assert.assertTrue(instance.getDataTypes(new LatLon(45.424722, -75.695)).get("buildings"));
|
||||
Assert.assertTrue(instance.getDataTypes(new LatLon(19.433333, -99.133333)).get("roads"));
|
||||
Assert.assertFalse(instance.getDataTypes(new LatLon(19.433333, -99.133333)).get("buildings"));
|
||||
}
|
||||
}
|
|
@ -14,8 +14,12 @@ import org.junit.Assert;
|
|||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.openstreetmap.josm.data.Bounds;
|
||||
import org.openstreetmap.josm.data.DataSource;
|
||||
import org.openstreetmap.josm.data.osm.DataSet;
|
||||
import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAILayer;
|
||||
import org.openstreetmap.josm.gui.MainApplication;
|
||||
import org.openstreetmap.josm.gui.layer.Layer;
|
||||
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
|
||||
import org.openstreetmap.josm.testutils.JOSMTestRules;
|
||||
|
||||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
|
@ -73,6 +77,48 @@ public class MapWithAILayerTest {
|
|||
Assert.assertEquals(tr("Switch Layers: {0}", false), label.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetLayer() {
|
||||
Layer mapWithAILayer = MapWithAIDataUtils.getLayer(false);
|
||||
Assert.assertNull(mapWithAILayer);
|
||||
|
||||
mapWithAILayer = MapWithAIDataUtils.getLayer(true);
|
||||
Assert.assertEquals(MapWithAILayer.class, mapWithAILayer.getClass());
|
||||
|
||||
Layer tMapWithAI = MapWithAIDataUtils.getLayer(false);
|
||||
Assert.assertSame(mapWithAILayer, tMapWithAI);
|
||||
|
||||
tMapWithAI = MapWithAIDataUtils.getLayer(true);
|
||||
Assert.assertSame(mapWithAILayer, tMapWithAI);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetData() {
|
||||
final MapWithAILayer mapWithAILayer = MapWithAIDataUtils.getLayer(true);
|
||||
final OsmDataLayer osm = new OsmDataLayer(new DataSet(), "test", null);
|
||||
MainApplication.getLayerManager().addLayer(osm);
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer, osm);
|
||||
|
||||
Assert.assertTrue(mapWithAILayer.getDataSet().getDataSourceBounds().isEmpty());
|
||||
|
||||
osm.getDataSet().addDataSource(new DataSource(new Bounds(0, 0, 0.001, 0.001), "random test"));
|
||||
|
||||
osm.lock();
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer);
|
||||
Assert.assertTrue(mapWithAILayer.getDataSet().getDataSourceBounds().isEmpty());
|
||||
osm.unlock();
|
||||
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer);
|
||||
Assert.assertFalse(mapWithAILayer.getDataSet().getDataSourceBounds().isEmpty());
|
||||
Assert.assertEquals(1, mapWithAILayer.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
|
||||
|
||||
osm.getDataSet().addDataSource(new DataSource(new Bounds(-0.001, -0.001, 0, 0), "random test"));
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer);
|
||||
Assert.assertEquals(2, mapWithAILayer.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
|
||||
|
||||
MapWithAIDataUtils.getMapWithAIData(mapWithAILayer);
|
||||
Assert.assertEquals(2, mapWithAILayer.getDataSet().getDataSourceBounds().parallelStream().distinct().count());
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue