From 10a36d0b6edfe5794ff0babdd66b0915cce8174f Mon Sep 17 00:00:00 2001
From: Justin Barno
Date: Mon, 14 Sep 2020 09:28:32 -0700
Subject: [PATCH] CCT 1.0.10 Release Notes
Features and improvements
This is a smaller release focused around creating and using bounding polygons in the CCT map.
Mapping
* Includes the Leaflet Geoman library to support drawing and editing bounding boxes and arbitrary polygons on the map
* Support for importing and exporting polygons is now included as a field in the calibration JSON definition as a GeoJSON formatted block
* Include/exclude options to toggle activation status on event/station pairs based on if they are bounded by a polygon
* Excludes require that both the station and the event meet the criteria, that is inside or outside the polygon, to be selected for disabling
* Includes require that **either** the station and the event meet the criteria, that is inside or outside the polygon, to be selected for enabling
* Added REST endpoints for managing polygon related tasks via service calls as well
Plotting
* Site/Measurement now plot the estimated corner frequency (~Fc) line on spectral plots when a fit is available.
---
README.md | 6 +-
calibration-gui/pom.xml | 8 +-
.../calibration/gui/CodaGuiController.java | 16 +-
.../AbstractMeasurementController.java | 24 +-
.../CodaParamLoadingController.java | 5 +
.../gui/controllers/DataController.java | 34 +--
.../controllers/MeasuredMwsController.java | 3 +-
.../gui/controllers/SiteController.java | 7 +-
.../controllers/SpectraPlotController.java | 10 +-
.../parameters/SharedBandController.java | 2 +-
.../converters/param/CodaJsonParamLoader.java | 6 +
.../gui/converters/param/RawGeoJSON.java | 27 +++
.../gui/data/client/ParameterWebClient.java | 21 +-
.../client/api/CalibrationJsonConstants.java | 5 +-
.../gui/data/client/api/ParameterClient.java | 5 +
.../data/exporters/JsonTempFileWriter.java | 9 +-
.../gui/data/exporters/ParamExporter.java | 7 +-
.../exporters/SwftStyleParamFileWriter.java | 2 +-
.../exporters/api/ParamTempFileWriter.java | 4 +-
.../gui/events/MapIconActivationCallback.java | 6 +
.../gui/events/MapPolygonChangeHandler.java | 36 +++
.../gui/events/UpdateMapPolygonEvent.java | 27 +++
.../gui/plotting/CodaWaveformPlotManager.java | 8 +-
.../gui/plotting/SpectralPlot.java | 53 +++--
.../src/main/resources/application.properties | 1 +
.../param/CodaJsonParamLoaderTest.java | 97 ++++----
.../resources/calibration-params-test.json | 18 ++
.../src/test/resources/logback-test.xml | 1 -
.../calibration-application/pom.xml | 2 +-
.../web/ConfigurationItemJsonController.java | 13 ++
.../web/GeometryJsonController.java | 66 ++++++
.../calibration-integration/pom.xml | 2 +-
calibration-service/calibration-model/pom.xml | 2 +-
.../model/domain/GeoJsonPolygon.java | 80 +++++++
.../calibration/model/domain/Spectra.java | 33 ++-
.../calibration-repository/pom.xml | 2 +-
.../repository/PolygonRepository.java | 23 ++
.../calibration-service-api/pom.xml | 2 +-
.../service/api/ConfigurationService.java | 4 +
.../service/api/GeometryService.java | 22 ++
.../calibration-service-impl/pom.xml | 19 +-
.../impl/ConfigurationServiceImpl.java | 18 +-
.../service/impl/GeometryServiceImpl.java | 138 ++++++++++++
.../processing/MdacCalculatorService.java | 4 +
.../impl/processing/SpectraCalculator.java | 14 +-
.../service/impl/GeometryServiceImplTest.java | 200 ++++++++++++++++
calibration-service/pom.xml | 2 +-
calibration-standalone/pom.xml | 2 +-
.../data/client/ParameterLocalClient.java | 16 +-
.../data/client/WaveformLocalClient.java | 16 +-
.../coda/calibration/AssessAutopicker.java | 28 ++-
common-gui/pom.xml | 2 +-
.../gui/data/client/WaveformWebClient.java | 20 ++
.../gui/data/client/api/WaveformClient.java | 4 +
.../gui/converters/sac/SacExporterTest.java | 22 +-
.../gui/converters/sac/SacLoaderTest.java | 22 +-
common-service/common-application/pom.xml | 2 +-
.../application/config/WebSocketConfig.java | 3 +-
.../common/util/NumberFormatFactoryTest.java | 8 +-
common-service/common-model/pom.xml | 2 +-
common-service/common-repository/pom.xml | 2 +-
.../common/repository/WaveformRepository.java | 31 ++-
common-service/common-service-api/pom.xml | 2 +-
common-service/common-service-impl/pom.xml | 2 +-
.../service/impl/WaveformServiceImpl.java | 2 +-
common-service/pom.xml | 2 +-
envelope-gui/pom.xml | 2 +-
envelope-service/envelope-application/pom.xml | 2 +-
envelope-service/envelope-model/pom.xml | 2 +-
envelope-service/envelope-repository/pom.xml | 2 +-
envelope-service/envelope-service-api/pom.xml | 2 +-
.../envelope-service-impl/pom.xml | 2 +-
envelope-service/pom.xml | 2 +-
envelope-standalone/pom.xml | 2 +-
externals/pom.xml | 2 +-
.../plotting/jmultiaxisplot/VPickLine.java | 3 +-
mapping/pom.xml | 2 +-
.../apps/coda/common/mapping/LeafletMap.java | 60 +++--
.../common/mapping/LeafletMapController.java | 12 +
.../mapping/MAP_CALLBACK_EVENT_TYPE.java | 4 +-
.../coda/common/mapping/MapCallbackEvent.java | 14 ++
.../apps/coda/common/mapping/api/GeoMap.java | 6 +-
.../apps/coda/common/mapping/api/Icon.java | 6 +-
.../main/resources/leaflet/images/Circle.svg | 15 ++
.../resources/leaflet/images/CircleMarker.svg | 7 +
.../resources/leaflet/images/Edit_Vertex.png | Bin 0 -> 2018 bytes
.../resources/leaflet/images/Edit_Vertex.svg | 11 +
.../main/resources/leaflet/images/Eraser.png | Bin 0 -> 2193 bytes
.../main/resources/leaflet/images/Eraser.svg | 17 ++
.../main/resources/leaflet/images/Line.svg | 11 +
.../main/resources/leaflet/images/Magnet.svg | 17 ++
.../main/resources/leaflet/images/Marker.svg | 17 ++
.../main/resources/leaflet/images/Move.png | Bin 0 -> 1456 bytes
.../main/resources/leaflet/images/Move.svg | 11 +
.../main/resources/leaflet/images/Polygon.png | Bin 0 -> 1847 bytes
.../main/resources/leaflet/images/Polygon.svg | 11 +
.../resources/leaflet/images/Rectangle.png | Bin 0 -> 2057 bytes
.../resources/leaflet/images/Rectangle.svg | 11 +
.../resources/leaflet/images/Scissors.svg | 17 ++
.../main/resources/leaflet/leaflet-geoman.css | 213 ++++++++++++++++++
.../resources/leaflet/leaflet-geoman.min.js | 1 +
.../src/main/resources/leaflet/leaflet.html | 141 +++++++++++-
pom.xml | 46 ++--
103 files changed, 1682 insertions(+), 271 deletions(-)
create mode 100644 calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/RawGeoJSON.java
create mode 100644 calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/events/MapPolygonChangeHandler.java
create mode 100644 calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/events/UpdateMapPolygonEvent.java
delete mode 100644 calibration-gui/src/test/resources/logback-test.xml
create mode 100644 calibration-service/calibration-application/src/main/java/gov/llnl/gnem/apps/coda/calibration/application/web/GeometryJsonController.java
create mode 100644 calibration-service/calibration-model/src/main/java/gov/llnl/gnem/apps/coda/calibration/model/domain/GeoJsonPolygon.java
create mode 100644 calibration-service/calibration-repository/src/main/java/gov/llnl/gnem/apps/coda/calibration/repository/PolygonRepository.java
create mode 100644 calibration-service/calibration-service-api/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/api/GeometryService.java
create mode 100644 calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/GeometryServiceImpl.java
create mode 100644 calibration-service/calibration-service-impl/src/test/java/gov/llnl/gnem/apps/coda/calibration/service/impl/GeometryServiceImplTest.java
create mode 100644 mapping/src/main/resources/leaflet/images/Circle.svg
create mode 100644 mapping/src/main/resources/leaflet/images/CircleMarker.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Edit_Vertex.png
create mode 100644 mapping/src/main/resources/leaflet/images/Edit_Vertex.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Eraser.png
create mode 100644 mapping/src/main/resources/leaflet/images/Eraser.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Line.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Magnet.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Marker.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Move.png
create mode 100644 mapping/src/main/resources/leaflet/images/Move.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Polygon.png
create mode 100644 mapping/src/main/resources/leaflet/images/Polygon.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Rectangle.png
create mode 100644 mapping/src/main/resources/leaflet/images/Rectangle.svg
create mode 100644 mapping/src/main/resources/leaflet/images/Scissors.svg
create mode 100644 mapping/src/main/resources/leaflet/leaflet-geoman.css
create mode 100644 mapping/src/main/resources/leaflet/leaflet-geoman.min.js
diff --git a/README.md b/README.md
index 5ced1505..628caf7d 100644
--- a/README.md
+++ b/README.md
@@ -42,18 +42,18 @@ We don't presently deploy versioned artifacts into a public repository like the
#### **As a single runnable JAR**
```shell
-java -jar coda-calibration/calibration-standalone/target/calibration-standalone-1.0.9-runnable.jar
+java -jar coda-calibration/calibration-standalone/target/calibration-standalone-1.0.10-runnable.jar
```
#### **GUI alone**
```shell
-java -jar coda-calibration/calibration-gui/target/calibration-gui-1.0.9-runnable.jar
+java -jar coda-calibration/calibration-gui/target/calibration-gui-1.0.10-runnable.jar
```
#### **Calibration REST service alone**
```shell
-java -jar coda-calibration/calibration-service/application/target/application-1.0.9-runnable.jar
+java -jar coda-calibration/calibration-service/application/target/application-1.0.10-runnable.jar
```
#### A note about HTTPS
diff --git a/calibration-gui/pom.xml b/calibration-gui/pom.xml
index 374102ca..6a7282a2 100644
--- a/calibration-gui/pom.xml
+++ b/calibration-gui/pom.xml
@@ -7,7 +7,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
calibration-gui
@@ -102,10 +102,6 @@
spring-boot-starter-webflux
-
- ch.qos.logback
- logback-classic
-
org.springframework
spring-test
@@ -177,7 +173,7 @@
org.springframework.boot
spring-boot-loader
-
+
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/CodaGuiController.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/CodaGuiController.java
index 1151ed41..5e22855f 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/CodaGuiController.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/CodaGuiController.java
@@ -50,9 +50,12 @@
import gov.llnl.gnem.apps.coda.calibration.gui.controllers.SiteController;
import gov.llnl.gnem.apps.coda.calibration.gui.controllers.parameters.ParametersController;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationClient;
+import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.ParameterClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.exporters.ParamExporter;
import gov.llnl.gnem.apps.coda.calibration.gui.events.CalibrationStageShownEvent;
import gov.llnl.gnem.apps.coda.calibration.gui.events.MapIconActivationCallback;
+import gov.llnl.gnem.apps.coda.calibration.gui.events.MapPolygonChangeHandler;
+import gov.llnl.gnem.apps.coda.calibration.gui.events.UpdateMapPolygonEvent;
import gov.llnl.gnem.apps.coda.calibration.gui.plotting.WaveformGui;
import gov.llnl.gnem.apps.coda.calibration.gui.util.CalibrationProgressListener;
import gov.llnl.gnem.apps.coda.calibration.gui.util.FileDialogs;
@@ -139,6 +142,8 @@ public class CodaGuiController {
private GeoMap mapController;
private WaveformClient waveformClient;
+
+ private ParameterClient configClient;
private EnvelopeLoadingController envelopeLoadingController;
@@ -179,7 +184,7 @@ public class CodaGuiController {
@Autowired
public CodaGuiController(GeoMap mapController, WaveformClient waveformClient, EnvelopeLoadingController waveformLoadingController, CodaParamLoadingController codaParamLoadingController,
ReferenceEventLoadingController refEventLoadingController, CalibrationClient calibrationClient, ParamExporter paramExporter, WaveformGui waveformGui, DataController data,
- ParametersController param, ShapeController shape, PathController path, SiteController site, MeasuredMwsController measuredMws, EventBus bus) {
+ ParametersController param, ShapeController shape, PathController path, SiteController site, MeasuredMwsController measuredMws, ParameterClient configClient, EventBus bus) {
super();
this.mapController = mapController;
this.waveformClient = waveformClient;
@@ -195,6 +200,7 @@ public CodaGuiController(GeoMap mapController, WaveformClient waveformClient, En
this.path = path;
this.site = site;
this.measuredMws = measuredMws;
+ this.configClient = configClient;
this.bus = bus;
bus.register(this);
@@ -335,6 +341,7 @@ public void initialize() {
waveformFocus.selectedProperty().bindBidirectional(waveformGui.focusProperty());
mapController.registerEventCallback(new MapIconActivationCallback(waveformClient));
+ mapController.registerEventCallback(new MapPolygonChangeHandler(configClient));
activeMapIcon = makeMapLabel();
showMapIcon = makeMapLabel();
@@ -450,6 +457,13 @@ private Label makeSnapshotLabel() {
return label;
}
+ @Subscribe
+ private void listener(UpdateMapPolygonEvent event) {
+ if (mapController != null && event != null && event.getGeoJSON() != null && !event.getGeoJSON().isEmpty()) {
+ mapController.setPolygonGeoJSON(event.getGeoJSON());
+ }
+ }
+
//TODO: Move this to a controller
@Subscribe
private void listener(CalibrationStatusEvent event) {
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/AbstractMeasurementController.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/AbstractMeasurementController.java
index 2f10a390..5d19be9d 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/AbstractMeasurementController.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/AbstractMeasurementController.java
@@ -14,8 +14,10 @@
package gov.llnl.gnem.apps.coda.calibration.gui.controllers;
import java.awt.Color;
+import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
@@ -52,8 +54,8 @@
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
-import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.ParameterClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.EventClient;
+import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.ParameterClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.SpectraClient;
import gov.llnl.gnem.apps.coda.calibration.gui.plotting.MapPlottingUtilities;
import gov.llnl.gnem.apps.coda.calibration.gui.plotting.SpectralPlot;
@@ -397,11 +399,19 @@ public void initialize() {
.asObject());
iconCol.setCellValueFactory(x -> Bindings.createObjectBinding(() -> Optional.ofNullable(x).map(CellDataFeatures::getValue).map(pp -> {
- ImageView imView = new ImageView(SwingFXUtils.toFXImage(SymbolFactory.createSymbol(pp.getStyle(), 0, 0, 2, pp.getColor(), pp.getColor(), pp.getColor(), "", true, false, 10.0)
- .getBufferedImage(256),
- null));
- imView.setFitHeight(12);
- imView.setFitWidth(12);
+ BufferedImage iconLayer = SymbolFactory.createSymbol(pp.getStyle(), 0, 0, 2.0, pp.getColor(), Color.BLACK, pp.getColor(), "", true, false, 10.0).getBufferedImage(216);
+ BufferedImage backgroundLayer = SymbolFactory.createSymbol(pp.getStyle(), 0, 0, 2.0, Color.BLACK, Color.BLACK, Color.BLACK, "", true, false, 10.0).getBufferedImage(256);
+
+ BufferedImage combined = new BufferedImage(backgroundLayer.getWidth(), backgroundLayer.getHeight(), BufferedImage.TYPE_INT_ARGB);
+
+ Graphics g = combined.getGraphics();
+ g.drawImage(backgroundLayer, 0, 0, null);
+ g.drawImage(iconLayer, 20, 20, null);
+ g.dispose();
+
+ ImageView imView = new ImageView(SwingFXUtils.toFXImage(combined, null));
+ imView.setFitHeight(16);
+ imView.setFitWidth(16);
return imView;
}).orElseGet(() -> new ImageView())));
@@ -466,7 +476,7 @@ private void plotSpectra() {
spectraControllers.forEach(spc -> {
if (fittingSpectra != null) {
- spc.getSpectralPlot().plotXYdata(toPlotPoints(filteredMeasurements, spc.getDataFunc()), SHOW_LEGEND, fittingSpectra);
+ spc.getSpectralPlot().plotXYdata(toPlotPoints(filteredMeasurements, spc.getDataFunc()), SHOW_LEGEND, fittingSpectra);
} else {
spc.getSpectralPlot().plotXYdata(toPlotPoints(filteredMeasurements, spc.getDataFunc()), HIDE_LEGEND);
}
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/CodaParamLoadingController.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/CodaParamLoadingController.java
index a3d3c093..e6de6731 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/CodaParamLoadingController.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/CodaParamLoadingController.java
@@ -32,9 +32,11 @@
import com.google.common.eventbus.EventBus;
import gov.llnl.gnem.apps.coda.calibration.gui.converters.api.FileToParameterConverter;
+import gov.llnl.gnem.apps.coda.calibration.gui.converters.param.RawGeoJSON;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.ParameterClient;
import gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.EventClient;
import gov.llnl.gnem.apps.coda.calibration.gui.events.ParametersLoadedEvent;
+import gov.llnl.gnem.apps.coda.calibration.gui.events.UpdateMapPolygonEvent;
import gov.llnl.gnem.apps.coda.calibration.model.domain.MdacParametersFI;
import gov.llnl.gnem.apps.coda.calibration.model.domain.MdacParametersPS;
import gov.llnl.gnem.apps.coda.calibration.model.domain.ReferenceMwParameters;
@@ -182,6 +184,9 @@ protected void convertFiles(List validFiles) {
} else {
log.error("Returned a null request from the parameter client while posting ShapeFitterConstraints {}", entry);
}
+ } else if (res.get() instanceof RawGeoJSON) {
+ RawGeoJSON entry = (RawGeoJSON) res.get();
+ bus.post(new UpdateMapPolygonEvent(entry.getRawGeoJSON()));
}
}
}
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/DataController.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/DataController.java
index 21cfd01b..7ebf9f2d 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/DataController.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/DataController.java
@@ -80,7 +80,7 @@ public class DataController implements MapListeningController, RefreshableContro
@FXML
private ScrollPane scrollPane;
-
+
@FXML
private TableView tableView;
@@ -101,7 +101,7 @@ public class DataController implements MapListeningController, RefreshableContro
@FXML
private TableColumn highFreqCol;
-
+
@FXML
private TableColumn depthCol;
@@ -210,20 +210,21 @@ private void reloadTable(ActionEvent e) {
@FXML
public void initialize() {
tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
- eventCol.setCellValueFactory(
- x -> Bindings.createStringBinding(() -> Optional.ofNullable(x).map(CellDataFeatures::getValue).map(Waveform::getEvent).map(Event::getEventId).orElseGet(String::new)));
+ eventCol.setCellValueFactory(x -> Bindings.createStringBinding(() -> Optional.ofNullable(x)
+ .map(CellDataFeatures::getValue)
+ .map(Waveform::getEvent)
+ .map(Event::getEventId)
+ .orElseGet(String::new)));
eventCol.comparatorProperty().set(new MaybeNumericStringComparator());
CellBindingUtils.attachTextCellFactories(lowFreqCol, Waveform::getLowFrequency, dfmt2);
CellBindingUtils.attachTextCellFactories(highFreqCol, Waveform::getHighFrequency, dfmt2);
-
- depthCol.setCellValueFactory(
- x -> Bindings.createStringBinding(
- () ->
- dfmt2.format(
- Optional.ofNullable(x).map(CellDataFeatures::getValue)
- .map(Waveform::getEvent)
- .map(ev->Double.toString(ev.getDepth())).orElseGet(String::new))));
+
+ depthCol.setCellValueFactory(x -> Bindings.createStringBinding(() -> Optional.ofNullable(x)
+ .map(CellDataFeatures::getValue)
+ .map(Waveform::getEvent)
+ .map(ev -> dfmt2.format(ev.getDepth()))
+ .orElseGet(String::new)));
depthCol.comparatorProperty().set(new MaybeNumericStringComparator());
usedCol.setCellValueFactory(x -> Bindings.createObjectBinding(() -> Optional.ofNullable(x).map(CellDataFeatures::getValue).map(waveform -> {
@@ -243,9 +244,12 @@ public void initialize() {
}).orElseGet(CheckBox::new)));
usedCol.comparatorProperty().set((c1, c2) -> Boolean.compare(c1.isSelected(), c2.isSelected()));
- stationCol.setCellValueFactory(
- x -> Bindings.createStringBinding(
- () -> Optional.ofNullable(x).map(CellDataFeatures::getValue).map(Waveform::getStream).map(Stream::getStation).map(Station::getStationName).orElseGet(String::new)));
+ stationCol.setCellValueFactory(x -> Bindings.createStringBinding(() -> Optional.ofNullable(x)
+ .map(CellDataFeatures::getValue)
+ .map(Waveform::getStream)
+ .map(Stream::getStation)
+ .map(Station::getStationName)
+ .orElseGet(String::new)));
tableView.getSelectionModel().getSelectedItems().addListener(tableChangeListener);
//Workaround for https://bugs.openjdk.java.net/browse/JDK-8095943, for now we just clear the selection to avoid dumping a stack trace in the logs and mucking up event bubbling
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/MeasuredMwsController.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/MeasuredMwsController.java
index ceb4dd9e..a5b36b48 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/MeasuredMwsController.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/MeasuredMwsController.java
@@ -133,6 +133,7 @@ public double getProgress() {
plot.addPlotObjectObserver(getPlotpointObserver(() -> spectra.getSymbolMap()));
plot.setLabels("Moment Rate Spectra", X_AXIS_LABEL, "log10(dyne-cm)");
plot.setYaxisVisibility(true);
+ spectra.setShowCornerFrequencies(true);
spectra.setYAxisResizable(true);
spectraPlotSwingNode.setContent(plot);
@@ -172,7 +173,7 @@ protected void preloadData() {
List refEvs = referenceEventClient.getMeasuredEventDetails()
.filter(ev -> ev.getEventId() != null)
.collect(Collectors.toList())
- .subscribeOn(Schedulers.elastic())
+ .subscribeOn(Schedulers.boundedElastic())
.block(Duration.ofSeconds(10l));
Collection measMws = mfs.getMeasuredMwDetails().values();
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/SiteController.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/SiteController.java
index b60d597b..caabb7ec 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/SiteController.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/SiteController.java
@@ -24,8 +24,6 @@
import javax.swing.SwingUtilities;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -52,8 +50,6 @@
@Component
public class SiteController extends AbstractMeasurementController {
- private static final Logger log = LoggerFactory.getLogger(SiteController.class);
-
private static final String X_AXIS_LABEL = "center freq";
private static final String displayName = "Site";
@@ -108,6 +104,7 @@ public void initialize() {
plot.addPlotObjectObserver(getPlotpointObserver(() -> site.getSymbolMap()));
plot.setLabels("Moment Rate Spectra", X_AXIS_LABEL, "log10(dyne-cm)");
plot.setYaxisVisibility(true);
+ site.setShowCornerFrequencies(true);
site.setYAxisResizable(true);
sitePlotSwingNode.setContent(plot);
@@ -155,7 +152,7 @@ protected List getEvents() {
return referenceEventClient.getMeasuredEventDetails()
.filter(ev -> ev.getEventId() != null)
.collect(Collectors.toList())
- .subscribeOn(Schedulers.elastic())
+ .subscribeOn(Schedulers.boundedElastic())
.block(Duration.ofSeconds(10l));
}
}
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/SpectraPlotController.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/SpectraPlotController.java
index da63f08a..d8353730 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/SpectraPlotController.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/SpectraPlotController.java
@@ -18,15 +18,11 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import gov.llnl.gnem.apps.coda.calibration.gui.plotting.SpectralPlot;
import gov.llnl.gnem.apps.coda.calibration.model.domain.SpectraMeasurement;
public class SpectraPlotController {
- private final Logger log = LoggerFactory.getLogger(this.getClass());
- private SpectralPlot spectraPlot = new SpectralPlot();;
+ private SpectralPlot spectraPlot = new SpectralPlot();
private Map spectraSymbolMap = new ConcurrentHashMap<>();
private boolean isYaxisResizble = false;
private Function dataFunction;
@@ -61,4 +57,8 @@ public void setYAxisResizable(boolean isYaxisResizble) {
public Function getDataFunc() {
return dataFunction;
}
+
+ public void setShowCornerFrequencies(boolean showCornerFrequencies) {
+ this.spectraPlot.showCornerFrequency(showCornerFrequencies);
+ }
}
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/parameters/SharedBandController.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/parameters/SharedBandController.java
index 7da849fa..c1df87f2 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/parameters/SharedBandController.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/controllers/parameters/SharedBandController.java
@@ -206,7 +206,7 @@ protected void requestData() {
.filter(Objects::nonNull)
.filter(value -> null != value.getId())
.doOnComplete(() -> Optional.ofNullable(codaSharedTableView).ifPresent(TableView::sort))
- .subscribe(value -> sharedFbData.add(value), err -> log.trace(err.getMessage(), err));
+ .subscribe(value -> sharedFbData.add(value), err -> log.error(err.getMessage(), err));
Optional.ofNullable(codaSharedTableView).ifPresent(v -> v.refresh());
});
}
diff --git a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/CodaJsonParamLoader.java b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/CodaJsonParamLoader.java
index 6647521f..feed7ade 100644
--- a/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/CodaJsonParamLoader.java
+++ b/calibration-gui/src/main/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/CodaJsonParamLoader.java
@@ -27,6 +27,7 @@
import static gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationJsonConstants.TYPE_VALUE;
import static gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationJsonConstants.VALIDATION_EVENTS_FIELD;
import static gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationJsonConstants.VELOCITY_CONFIGURATION;
+import static gov.llnl.gnem.apps.coda.calibration.gui.data.client.api.CalibrationJsonConstants.POLYGON_FIELD;
import java.io.File;
import java.io.IOException;
@@ -114,6 +115,7 @@ public List> convertJsonParamFile(File file) {
results.addAll(convertJsonFields(node, VALIDATION_EVENTS_FIELD, x -> valEventsFromJsonNode(x)));
results.addAll(convertJsonFields(node, VELOCITY_CONFIGURATION, x -> velocityConfigurationFromJsonNode(x)));
results.addAll(convertJsonFields(node, SHAPE_CONSTRAINTS, x -> shapeConstraintsFromJsonNode(x)));
+ results.addAll(convertJsonFields(node, POLYGON_FIELD, x -> polygonFromJsonNode(x)));
} else if (node.has(ENVELOPE_JOB_NODE)) {
results.addAll(convertJsonFields(node, ENVELOPE_JOB_NODE, x -> envelopeJobBandsToSharedBands(x)));
}
@@ -124,6 +126,10 @@ public List> convertJsonParamFile(File file) {
return results;
}
+ private Result
*/
- public void plotXYdata(final List plots, Boolean showLegend, List spectra) {
-
+ public void plotXYdata(final List plots, Boolean showLegend, List spectra) {
symbolMap.clear();
// line based legends for trending
Legend legend = new Legend(getTitle().getFontName(), getTitle().getFontSize(), HorizPinEdge.RIGHT, VertPinEdge.TOP, 5, 5);
@@ -177,6 +180,9 @@ public void plotXYdata(final List plots, Boolean showLegend, List (s1.getType() == SPECTRA_TYPES.UQ1 || s1.getType() == SPECTRA_TYPES.UQ2) ? -1 : 1);
for (Spectra spec : spectra) {
+ if (plotCorners && spec.getCornerFrequency() != null) {
+ plotCornerFrequency(spec.getCornerFrequency());
+ }
plotSpectraObject(jsubplot, spec, legend);
}
}
@@ -192,6 +198,10 @@ public void plotXYdata(final List plots, Boolean showLegend, List netMwValues = spectra.getSpectraXY().stream().map(d -> new PlotPoint(d.getX(), d.getY(), null, null)).collect(Collectors.toList());
@@ -210,7 +220,7 @@ private void plotSpectraObject(JSubplot jsubplot, Spectra spectra, Legend legend
break;
case VAL:
line = new Line(x, y, Color.BLUE, PaintMode.COPY, PenStyle.DASHDOT, 2);
- break;
+ break;
case UQ1:
line = new Line(x, y, Color.LIGHT_GRAY, PaintMode.COPY, PenStyle.DASH, 2);
break;
@@ -330,18 +340,17 @@ public final void plotXYdata(List data) {
} else {
label = "";
}
- Symbol symbol = SymbolFactory.createSymbol(
- v.getStyle(),
- v.getX(),
- v.getY(),
- properties.getSymbolSize(),
- v.getColor(),
- properties.getSymbolEdgeColor(),
- v.getColor(),
- label,
- true,
- false,
- 10.0);
+ Symbol symbol = SymbolFactory.createSymbol(v.getStyle(),
+ v.getX(),
+ v.getY(),
+ properties.getSymbolSize(),
+ v.getColor(),
+ properties.getSymbolEdgeColor(),
+ v.getColor(),
+ label,
+ true,
+ false,
+ 10.0);
symbolMap.computeIfAbsent(new Point2D.Double(v.getX(), v.getY()), key -> new ArrayList<>()).add(symbol);
return symbol;
}).forEach(jsubplot::AddPlotObject);
@@ -370,7 +379,7 @@ public void rescalePlot(double x, double y) {
}
@Override
- public void setAllXlimits(double xmin, double xmax) {
+ public void setAllXlimits(double xmin, double xmax) {
super.setAllXlimits(xmin, xmax);
properties.setMaxXAxisValue(xmax);
properties.setMinXAxisValue(xmin);
@@ -383,13 +392,13 @@ public void setAllXlimits() {
properties.setMinXAxisValue(xmin);
}
- public void setAllYlimits(double ymin, double ymax) {
+ public void setAllYlimits(double ymin, double ymax) {
jsubplot.setYlimits(ymin, ymax);
this.ymin = ymin;
this.ymax = ymax;
}
- public void setAllYlimits() {
+ public void setAllYlimits() {
jsubplot.setYlimits(defaultYMin, defaultYMax);
this.ymin = defaultYMin;
this.ymax = defaultYMax;
@@ -416,7 +425,7 @@ public void refreshPlotAxes() {
xMin = properties.getMinXAxisValue();
xMax = properties.getMaxXAxisValue();
}
- jsubplot.setAxisLimits(xMin, xMax, yMin, yMax);
+ jsubplot.setAxisLimits(xMin, xMax, yMin, yMax);
}
/** Set the Title, X and Y axis labels simultaneously */
@@ -503,4 +512,8 @@ public void deselectPoint(Point2D.Double xyPoint) {
}
repaint();
}
+
+ public void showCornerFrequency(boolean showCornerFreq) {
+ this.plotCorners = showCornerFreq;
+ }
}
diff --git a/calibration-gui/src/main/resources/application.properties b/calibration-gui/src/main/resources/application.properties
index d35e6960..a2093e16 100644
--- a/calibration-gui/src/main/resources/application.properties
+++ b/calibration-gui/src/main/resources/application.properties
@@ -1,4 +1,5 @@
spring.output.ansi.enabled=ALWAYS
+logging.level.javafx.*=off
logging.level.org.springframework.web.socket.*=off
logging.level.org.springframework.web.reactive.function.client.*=off
webclient.basePath=localhost:53921
diff --git a/calibration-gui/src/test/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/CodaJsonParamLoaderTest.java b/calibration-gui/src/test/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/CodaJsonParamLoaderTest.java
index eed5b4c0..59817330 100644
--- a/calibration-gui/src/test/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/CodaJsonParamLoaderTest.java
+++ b/calibration-gui/src/test/java/gov/llnl/gnem/apps/coda/calibration/gui/converters/param/CodaJsonParamLoaderTest.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -21,12 +21,13 @@
import java.util.Collections;
import java.util.stream.Stream;
-import org.junit.Assert;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
+import gov.llnl.gnem.apps.coda.calibration.model.domain.GeoJsonPolygon;
import gov.llnl.gnem.apps.coda.calibration.model.domain.MdacParametersFI;
import gov.llnl.gnem.apps.coda.calibration.model.domain.MdacParametersPS;
import gov.llnl.gnem.apps.coda.calibration.model.domain.ReferenceMwParameters;
@@ -58,10 +59,7 @@ protected Flux> convertFile(String filePath) {
@MethodSource("filePaths")
public final void testValidBands(String filePath) throws Exception {
Flux> results = convertFile(filePath);
- Assert.assertEquals(
- "Expected to have 14 valid band definitions",
- Long.valueOf(14l),
- results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof SharedFrequencyBandParameters).count().block());
+ Assertions.assertEquals(Long.valueOf(14l), results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof SharedFrequencyBandParameters).count().block());
}
@ParameterizedTest
@@ -72,72 +70,81 @@ public final void testValidSiteCorrections(String filePath) throws Exception {
.blockFirst()
.getResultPayload()
.orElseGet(null);
- Assert.assertNotNull("Expected to have 1 site correction object", siteCorrections);
- Assert.assertEquals("Expected to have 1 networks", 1, siteCorrections.getSiteCorrections().stream().map(sc -> sc.getStation().getNetworkName()).distinct().count());
- Assert.assertEquals("Expected to have 3 stations", 3, siteCorrections.getSiteCorrections().stream().map(sc -> sc.getStation().getStationName()).distinct().count());
- Assert.assertEquals(
- "Expected to have 14 bands for the first station",
- 14,
- siteCorrections.getSiteCorrections()
- .stream()
- .filter(
- sfb -> sfb.getStation()
- .getStationName()
- .equalsIgnoreCase(siteCorrections.getSiteCorrections().stream().map(sc -> sc.getStation().getStationName()).findFirst().orElseGet(null)))
- .count());
- Assert.assertEquals("Expected to have 42 site correction bands", 42, siteCorrections.getSiteCorrections().size());
+ Assertions.assertNotNull(siteCorrections, "Expected to have 1 site correction object");
+ Assertions.assertEquals(1, siteCorrections.getSiteCorrections().stream().map(sc -> sc.getStation().getNetworkName()).distinct().count(), "Expected to have 1 networks");
+ Assertions.assertEquals(3, siteCorrections.getSiteCorrections().stream().map(sc -> sc.getStation().getStationName()).distinct().count(), "Expected to have 3 stations");
+ Assertions.assertEquals(14,
+ siteCorrections.getSiteCorrections()
+ .stream()
+ .filter(sfb -> sfb.getStation()
+ .getStationName()
+ .equalsIgnoreCase(siteCorrections.getSiteCorrections()
+ .stream()
+ .map(sc -> sc.getStation().getStationName())
+ .findFirst()
+ .orElseGet(null)))
+ .count(),
+ "Expected to have 14 bands for the first station");
+ Assertions.assertEquals(42, siteCorrections.getSiteCorrections().size(), "Expected to have 42 site correction bands");
}
@ParameterizedTest
@MethodSource("filePaths")
public final void testValidPs(String filePath) throws Exception {
Flux> results = convertFile(filePath);
- Assert.assertEquals(
- "Expected to have 1 valid MDAC FI definition",
- Long.valueOf(1l),
- results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof MdacParametersFI).count().block());
+ Assertions.assertEquals(Long.valueOf(1l),
+ results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof MdacParametersFI).count().block(),
+ "Expected to have 1 valid MDAC FI definition");
}
@ParameterizedTest
@MethodSource("filePaths")
public final void testFi(String filePath) throws Exception {
Flux> results = convertFile(filePath);
- Assert.assertEquals(
- "Expected to have 4 valid MDAC PS definitions",
- Long.valueOf(4l),
- results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof MdacParametersPS).count().block());
+ Assertions.assertEquals(Long.valueOf(4l),
+ results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof MdacParametersPS).count().block(),
+ "Expected to have 4 valid MDAC PS definitions");
}
@ParameterizedTest
@MethodSource("filePaths")
public final void testRefMw(String filePath) throws Exception {
Flux> results = convertFile(filePath);
- Assert.assertEquals(
- "Expected to have 2 valid reference event definitions",
- Long.valueOf(2l),
- results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof ReferenceMwParameters).count().block());
+ Assertions.assertEquals(Long.valueOf(2l),
+ results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof ReferenceMwParameters).count().block(),
+ "Expected to have 2 valid reference event definitions");
}
-
+
@ParameterizedTest
@MethodSource("filePaths")
public final void testValidationMw(String filePath) throws Exception {
Flux> results = convertFile(filePath);
- Assert.assertEquals(
- "Expected to have 2 valid validation event definitions",
- Long.valueOf(2l),
- results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof ValidationMwParameters).count().block());
- }
+ Assertions.assertEquals(Long.valueOf(2l),
+ results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof ValidationMwParameters).count().block(),
+ "Expected to have 14 valid band definitions");
+ }
+
+ @ParameterizedTest
+ @MethodSource("filePaths")
+ public final void testMultiplePolygons(String filePath) throws Exception {
+ Flux> results = convertFile(filePath);
+ RawGeoJSON result = (RawGeoJSON) results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof RawGeoJSON).blockFirst().getResultPayload().get();
+
+ Assertions.assertEquals("{\"features\":[{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[0.0,3.0],[3.0,3.0],[3.0,0.0],[0.0,0.0],[0.0,3.0]]]}}]}",
+ result.getRawGeoJSON(),
+ "Expected RawGeoJSON collection to match contents of calibration JSON");
+ }
@ParameterizedTest
@MethodSource("filePaths")
public final void testShapeConstraint(String filePath) throws Exception {
Flux> results = convertFile(filePath);
- Assert.assertEquals(
- "Expected to have 1 valid shape constraint definition",
- Long.valueOf(1l),
- results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof ShapeFitterConstraints).count().block());
- assertThat(((ShapeFitterConstraints) results.filter(r -> r.getResultPayload().orElse(null) instanceof ShapeFitterConstraints).blockFirst().getResultPayload().get()).getMaxBeta()).isCloseTo(
- -11.0E-4,
- within(0.001)).describedAs("Expected values containing 'E-' scientific notation serialize correctly");
+ Assertions.assertEquals(Long.valueOf(1l),
+ results.filter(r -> r.isSuccess() && r.getResultPayload().orElse(null) instanceof ShapeFitterConstraints).count().block(),
+ "Expected to have 1 valid shape constraint definition");
+ assertThat(((ShapeFitterConstraints) results.filter(r -> r.getResultPayload().orElse(null) instanceof ShapeFitterConstraints)
+ .blockFirst()
+ .getResultPayload()
+ .get()).getMaxBeta()).isCloseTo(-11.0E-4, within(0.001)).describedAs("Expected values containing 'E-' scientific notation serialize correctly");
}
}
diff --git a/calibration-gui/src/test/resources/calibration-params-test.json b/calibration-gui/src/test/resources/calibration-params-test.json
index 86caf0b6..016d600a 100644
--- a/calibration-gui/src/test/resources/calibration-params-test.json
+++ b/calibration-gui/src/test/resources/calibration-params-test.json
@@ -200,6 +200,24 @@
"apparentStressInMpa": 0.7
}
],
+ "polygons": {
+ "features": [{
+ "type": "Feature",
+ "properties": {},
+ "geometry": {
+ "type": "Polygon",
+ "coordinates": [
+ [
+ [0.0, 3.0],
+ [3.0, 3.0],
+ [3.0, 0.0],
+ [0.0, 0.0],
+ [0.0, 3.0]
+ ]
+ ]
+ }
+ }]
+ },
"shape-constraints": {
"maxVP1": 1600.0,
"minVP1": 150.0,
diff --git a/calibration-gui/src/test/resources/logback-test.xml b/calibration-gui/src/test/resources/logback-test.xml
deleted file mode 100644
index adfa02c6..00000000
--- a/calibration-gui/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/calibration-service/calibration-application/pom.xml b/calibration-service/calibration-application/pom.xml
index 15316612..f183dc94 100644
--- a/calibration-service/calibration-application/pom.xml
+++ b/calibration-service/calibration-application/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibration
calibration-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/calibration-service/calibration-application/src/main/java/gov/llnl/gnem/apps/coda/calibration/application/web/ConfigurationItemJsonController.java b/calibration-service/calibration-application/src/main/java/gov/llnl/gnem/apps/coda/calibration/application/web/ConfigurationItemJsonController.java
index 5043ea4c..f76c8f67 100644
--- a/calibration-service/calibration-application/src/main/java/gov/llnl/gnem/apps/coda/calibration/application/web/ConfigurationItemJsonController.java
+++ b/calibration-service/calibration-application/src/main/java/gov/llnl/gnem/apps/coda/calibration/application/web/ConfigurationItemJsonController.java
@@ -69,4 +69,17 @@ public ResponseEntity> updateShapeFitterConstraints(@Valid @RequestBody ShapeF
configService.update(entry);
return ResponseEntity.ok().build();
}
+
+ @GetMapping(value = "/polygon", name = "getPolygon")
+ public ResponseEntity getPolygon() {
+ return ResponseEntity.ok().body(configService.getPolygonGeoJSON());
+ }
+
+ @PostMapping(value = "/polygon/update", name = "updatePolygon")
+ public ResponseEntity> updatePolygon(@Valid @RequestBody String rawGeoJSON, BindingResult result) {
+ if (result.hasErrors()) {
+ return ResponseEntity.status(HttpStatus.CONFLICT).body(result);
+ }
+ return ResponseEntity.ok().body(configService.updatePolygon(rawGeoJSON));
+ }
}
diff --git a/calibration-service/calibration-application/src/main/java/gov/llnl/gnem/apps/coda/calibration/application/web/GeometryJsonController.java b/calibration-service/calibration-application/src/main/java/gov/llnl/gnem/apps/coda/calibration/application/web/GeometryJsonController.java
new file mode 100644
index 00000000..6b7231ee
--- /dev/null
+++ b/calibration-service/calibration-application/src/main/java/gov/llnl/gnem/apps/coda/calibration/application/web/GeometryJsonController.java
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.calibration.application.web;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import gov.llnl.gnem.apps.coda.calibration.service.api.GeometryService;
+
+@RestController
+@RequestMapping(value = "/api/v1/geometry", name = "GeometryJsonController", produces = MediaType.APPLICATION_JSON_VALUE)
+public class GeometryJsonController {
+
+ private static final Logger log = LoggerFactory.getLogger(GeometryJsonController.class);
+
+ private GeometryService service;
+
+ @Autowired
+ public GeometryJsonController(GeometryService service) {
+ this.service = service;
+ }
+
+ @PostMapping(value = "/set-active/waveforms-inside-polygon/{active}", name = "measureMws")
+ public ResponseEntity> setActiveFlagInsidePolygon(@PathVariable Boolean active) {
+ ResponseEntity> resp = null;
+ try {
+ service.setActiveFlagInsidePolygon(active);
+ resp = ResponseEntity.ok().build();
+ } catch (RuntimeException ex) {
+ log.trace(ex.getLocalizedMessage());
+ }
+ return resp == null ? ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build() : resp;
+ }
+
+ @PostMapping(value = "/set-active/waveforms-outside-polygon/{active}", name = "measureMws")
+ public ResponseEntity> setActiveFlagOutsidePolygon(@PathVariable Boolean active) {
+ ResponseEntity> resp = null;
+ try {
+ service.setActiveFlagOutsidePolygon(active);
+ resp = ResponseEntity.ok().build();
+ } catch (RuntimeException ex) {
+ log.trace(ex.getLocalizedMessage());
+ }
+ return resp == null ? ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build() : resp;
+ }
+}
diff --git a/calibration-service/calibration-integration/pom.xml b/calibration-service/calibration-integration/pom.xml
index 001db916..7a50a639 100644
--- a/calibration-service/calibration-integration/pom.xml
+++ b/calibration-service/calibration-integration/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.calibration
calibration-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/calibration-service/calibration-model/pom.xml b/calibration-service/calibration-model/pom.xml
index cc931d11..d2e99094 100644
--- a/calibration-service/calibration-model/pom.xml
+++ b/calibration-service/calibration-model/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibration
calibration-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/calibration-service/calibration-model/src/main/java/gov/llnl/gnem/apps/coda/calibration/model/domain/GeoJsonPolygon.java b/calibration-service/calibration-model/src/main/java/gov/llnl/gnem/apps/coda/calibration/model/domain/GeoJsonPolygon.java
new file mode 100644
index 00000000..b96774a8
--- /dev/null
+++ b/calibration-service/calibration-model/src/main/java/gov/llnl/gnem/apps/coda/calibration/model/domain/GeoJsonPolygon.java
@@ -0,0 +1,80 @@
+/*
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.calibration.model.domain;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+import javax.persistence.Basic;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Lob;
+import javax.persistence.Table;
+import javax.persistence.Version;
+
+@Entity
+@Table(name = "Polygons")
+public class GeoJsonPolygon implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ @Column(name = "ID")
+ private Long id;
+
+ @Version
+ private Integer version = 0;
+
+ @Lob
+ @Basic
+ private String rawGeoJson = "";
+
+ public String getRawGeoJson() {
+ return rawGeoJson;
+ }
+
+ public GeoJsonPolygon setRawGeoJson(String rawGeoJson) {
+ this.rawGeoJson = rawGeoJson;
+ return this;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, rawGeoJson, version);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof GeoJsonPolygon)) {
+ return false;
+ }
+ GeoJsonPolygon other = (GeoJsonPolygon) obj;
+ return Objects.equals(id, other.id) && Objects.equals(rawGeoJson, other.rawGeoJson) && Objects.equals(version, other.version);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("GeoJsonPolygon [id=").append(id).append(", version=").append(version).append(", rawGeoJson=").append(rawGeoJson).append("]");
+ return builder.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/calibration-service/calibration-model/src/main/java/gov/llnl/gnem/apps/coda/calibration/model/domain/Spectra.java b/calibration-service/calibration-model/src/main/java/gov/llnl/gnem/apps/coda/calibration/model/domain/Spectra.java
index e5a1b6ec..e198819a 100644
--- a/calibration-service/calibration-model/src/main/java/gov/llnl/gnem/apps/coda/calibration/model/domain/Spectra.java
+++ b/calibration-service/calibration-model/src/main/java/gov/llnl/gnem/apps/coda/calibration/model/domain/Spectra.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -25,6 +25,7 @@ public class Spectra {
private List xyVals;
private double apparentStress = -1;
private double mw = -1;
+ private Double cornerFrequency = null;
private SPECTRA_TYPES type;
/**
@@ -34,7 +35,7 @@ public class Spectra {
* @param mw
* @param stress
*/
- public Spectra(SPECTRA_TYPES type, List xyVals, Double mw, Double stress) {
+ public Spectra(SPECTRA_TYPES type, List xyVals, Double mw, Double stress, Double cornerFrequency) {
this.type = type;
this.xyVals = xyVals;
if (mw != null) {
@@ -43,6 +44,9 @@ public Spectra(SPECTRA_TYPES type, List xyVals, Do
if (stress != null) {
this.apparentStress = stress;
}
+ if (cornerFrequency != null) {
+ this.cornerFrequency = cornerFrequency;
+ }
}
public Spectra() {
@@ -66,9 +70,13 @@ public SPECTRA_TYPES getType() {
return type;
}
+ public Double getCornerFrequency() {
+ return cornerFrequency;
+ }
+
@Override
public int hashCode() {
- return Objects.hash(apparentStress, mw, type, xyVals);
+ return Objects.hash(apparentStress, cornerFrequency, mw, type, xyVals);
}
@Override
@@ -80,16 +88,25 @@ public boolean equals(Object obj) {
return false;
}
Spectra other = (Spectra) obj;
- return Double.doubleToLongBits(apparentStress) == Double.doubleToLongBits(other.apparentStress)
- && Double.doubleToLongBits(mw) == Double.doubleToLongBits(other.mw)
- && type == other.type
- && Objects.equals(xyVals, other.xyVals);
+ return Double.doubleToLongBits(apparentStress) == Double.doubleToLongBits(other.apparentStress) && Objects.equals(cornerFrequency, other.cornerFrequency)
+ && Double.doubleToLongBits(mw) == Double.doubleToLongBits(other.mw) && type == other.type && Objects.equals(xyVals, other.xyVals);
}
@Override
public String toString() {
+ final int maxLen = 10;
StringBuilder builder = new StringBuilder();
- builder.append("Spectra [xyVals=").append(xyVals).append(", apparentStress=").append(apparentStress).append(", mw=").append(mw).append(", type=").append(type).append("]");
+ builder.append("Spectra [xyVals=")
+ .append(xyVals != null ? xyVals.subList(0, Math.min(xyVals.size(), maxLen)) : null)
+ .append(", apparentStress=")
+ .append(apparentStress)
+ .append(", mw=")
+ .append(mw)
+ .append(", cornerFrequency=")
+ .append(cornerFrequency)
+ .append(", type=")
+ .append(type)
+ .append("]");
return builder.toString();
}
}
diff --git a/calibration-service/calibration-repository/pom.xml b/calibration-service/calibration-repository/pom.xml
index 6b424794..a2660b2c 100644
--- a/calibration-service/calibration-repository/pom.xml
+++ b/calibration-service/calibration-repository/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibration
calibration-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/calibration-service/calibration-repository/src/main/java/gov/llnl/gnem/apps/coda/calibration/repository/PolygonRepository.java b/calibration-service/calibration-repository/src/main/java/gov/llnl/gnem/apps/coda/calibration/repository/PolygonRepository.java
new file mode 100644
index 00000000..73a6892a
--- /dev/null
+++ b/calibration-service/calibration-repository/src/main/java/gov/llnl/gnem/apps/coda/calibration/repository/PolygonRepository.java
@@ -0,0 +1,23 @@
+/*
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.calibration.repository;
+
+import org.springframework.transaction.annotation.Transactional;
+
+import gov.llnl.gnem.apps.coda.calibration.model.domain.GeoJsonPolygon;
+import gov.llnl.gnem.apps.coda.common.repository.DetachableJpaRepository;
+
+@Transactional
+public interface PolygonRepository extends DetachableJpaRepository {
+}
diff --git a/calibration-service/calibration-service-api/pom.xml b/calibration-service/calibration-service-api/pom.xml
index e8ea6d36..519598bb 100644
--- a/calibration-service/calibration-service-api/pom.xml
+++ b/calibration-service/calibration-service-api/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.calibration
calibration-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/calibration-service/calibration-service-api/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/api/ConfigurationService.java b/calibration-service/calibration-service-api/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/api/ConfigurationService.java
index 39a5b1e0..b1c1810a 100644
--- a/calibration-service/calibration-service-api/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/api/ConfigurationService.java
+++ b/calibration-service/calibration-service-api/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/api/ConfigurationService.java
@@ -25,4 +25,8 @@ public interface ConfigurationService {
public ShapeFitterConstraints update(ShapeFitterConstraints entry);
public ShapeFitterConstraints getCalibrationShapeFitterConstraints();
+
+ public String updatePolygon(String rawGeoJSON);
+
+ public String getPolygonGeoJSON();
}
diff --git a/calibration-service/calibration-service-api/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/api/GeometryService.java b/calibration-service/calibration-service-api/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/api/GeometryService.java
new file mode 100644
index 00000000..87cb0ea9
--- /dev/null
+++ b/calibration-service/calibration-service-api/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/api/GeometryService.java
@@ -0,0 +1,22 @@
+/*
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.calibration.service.api;
+
+import java.util.List;
+
+public interface GeometryService {
+ public List setActiveFlagOutsidePolygon(boolean active);
+
+ public List setActiveFlagInsidePolygon(boolean active);
+}
diff --git a/calibration-service/calibration-service-impl/pom.xml b/calibration-service/calibration-service-impl/pom.xml
index 1bf4766a..b2f719e1 100644
--- a/calibration-service/calibration-service-impl/pom.xml
+++ b/calibration-service/calibration-service-impl/pom.xml
@@ -1,11 +1,10 @@
-
gov.llnl.gnem.apps.coda.calibration
calibration-service
- 1.0.9
+ 1.0.10
4.0.0
@@ -101,7 +100,7 @@
assertj-core
test
-
+
org.springframework.boot
spring-boot-starter-test
test
@@ -116,6 +115,18 @@
h2
test
+
+ org.locationtech.jts
+ jts-core
+
+
+ org.locationtech.jts.io
+ jts-io-common
+
+
+ org.wololo
+ jts2geojson
+
diff --git a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/ConfigurationServiceImpl.java b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/ConfigurationServiceImpl.java
index 1e3fa0e9..58c5f4c1 100644
--- a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/ConfigurationServiceImpl.java
+++ b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/ConfigurationServiceImpl.java
@@ -20,11 +20,13 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import gov.llnl.gnem.apps.coda.calibration.model.domain.GeoJsonPolygon;
import gov.llnl.gnem.apps.coda.calibration.model.domain.ShapeFitterConstraints;
import gov.llnl.gnem.apps.coda.calibration.model.domain.VelocityConfiguration;
import gov.llnl.gnem.apps.coda.calibration.model.messaging.GvDataChangeEvent;
import gov.llnl.gnem.apps.coda.calibration.model.messaging.ShapeConstraintsChangeEvent;
import gov.llnl.gnem.apps.coda.calibration.repository.CalibrationShapeFitterConstraintsRepository;
+import gov.llnl.gnem.apps.coda.calibration.repository.PolygonRepository;
import gov.llnl.gnem.apps.coda.calibration.repository.VelocityConfigurationRepository;
import gov.llnl.gnem.apps.coda.calibration.service.api.ConfigurationService;
import gov.llnl.gnem.apps.coda.common.service.api.NotificationService;
@@ -36,18 +38,20 @@ public class ConfigurationServiceImpl implements ConfigurationService {
private EntityManager em;
private VelocityConfigurationRepository velConfRepository;
private CalibrationShapeFitterConstraintsRepository shapeConstraintsRepository;
+ private PolygonRepository polygonRepository;
private VelocityConfiguration defaultVelConf;
private ShapeFitterConstraints defaultShapeFitterConstraint;
private NotificationService notificationService;
@Autowired
public ConfigurationServiceImpl(EntityManager em, VelocityConfigurationRepository velConfRepository, CalibrationShapeFitterConstraintsRepository shapeConstraintsRepository,
- VelocityConfiguration defaultVelConf, ShapeFitterConstraints defaultShapeFitterConstraint, NotificationService notificationService) {
+ VelocityConfiguration defaultVelConf, ShapeFitterConstraints defaultShapeFitterConstraint, PolygonRepository polygonRepository, NotificationService notificationService) {
this.em = em;
this.velConfRepository = velConfRepository;
this.shapeConstraintsRepository = shapeConstraintsRepository;
this.defaultVelConf = defaultVelConf;
this.defaultShapeFitterConstraint = defaultShapeFitterConstraint;
+ this.polygonRepository = polygonRepository;
this.notificationService = notificationService;
}
@@ -104,4 +108,16 @@ public ShapeFitterConstraints getCalibrationShapeFitterConstraints() {
em.detach(res);
return res;
}
+
+ @Override
+ public String updatePolygon(String rawGeoJSON) {
+ //TODO: Support multiples/additive updates
+ polygonRepository.deleteAll();
+ return polygonRepository.save(new GeoJsonPolygon().setRawGeoJson(rawGeoJSON)).getRawGeoJson();
+ };
+
+ @Override
+ public String getPolygonGeoJSON() {
+ return polygonRepository.findAll().stream().findAny().orElseGet(GeoJsonPolygon::new).getRawGeoJson();
+ }
}
diff --git a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/GeometryServiceImpl.java b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/GeometryServiceImpl.java
new file mode 100644
index 00000000..21ff3ee0
--- /dev/null
+++ b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/GeometryServiceImpl.java
@@ -0,0 +1,138 @@
+/*
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.calibration.service.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.stream.Collectors;
+
+import org.locationtech.jts.algorithm.locate.IndexedPointInAreaLocator;
+import org.locationtech.jts.geom.Coordinate;
+import org.locationtech.jts.geom.Geometry;
+import org.locationtech.jts.geom.Location;
+import org.locationtech.jts.geom.util.GeometryCombiner;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.wololo.geojson.Feature;
+import org.wololo.geojson.FeatureCollection;
+import org.wololo.geojson.GeoJSONFactory;
+import org.wololo.jts2geojson.GeoJSONReader;
+
+import gov.llnl.gnem.apps.coda.calibration.model.domain.GeoJsonPolygon;
+import gov.llnl.gnem.apps.coda.calibration.repository.PolygonRepository;
+import gov.llnl.gnem.apps.coda.calibration.service.api.GeometryService;
+import gov.llnl.gnem.apps.coda.common.model.domain.Waveform;
+import gov.llnl.gnem.apps.coda.common.model.messaging.WaveformChangeEvent;
+import gov.llnl.gnem.apps.coda.common.repository.WaveformRepository;
+import gov.llnl.gnem.apps.coda.common.service.api.NotificationService;
+
+@Service
+public class GeometryServiceImpl implements GeometryService {
+
+ private static final Logger log = LoggerFactory.getLogger(GeometryServiceImpl.class);
+
+ private WaveformRepository waveformRepository;
+ private PolygonRepository polygonRepository;
+ private NotificationService notificationService;
+
+ @Autowired
+ public GeometryServiceImpl(WaveformRepository waveformRepository, PolygonRepository polygonRepository, NotificationService notificationService) {
+ this.waveformRepository = waveformRepository;
+ this.polygonRepository = polygonRepository;
+ this.notificationService = notificationService;
+ }
+
+ @Override
+ public List setActiveFlagOutsidePolygon(boolean active) {
+ return toggleActiveByPolygon(false, active);
+ }
+
+ @Override
+ public List setActiveFlagInsidePolygon(boolean active) {
+ return toggleActiveByPolygon(true, active);
+ }
+
+ private List toggleActiveByPolygon(boolean inside, boolean active) {
+ List ids = new ArrayList<>();
+
+ List geoJSON = polygonRepository.findAll();
+ List selectedWaveformIds = findIdsByPolygonAndActiveStatus(geoJSON, inside, !active);
+
+ if (!selectedWaveformIds.isEmpty()) {
+ int updatedRows = waveformRepository.setActiveIn(active, selectedWaveformIds);
+ if (updatedRows > 0) {
+ ids.addAll(selectedWaveformIds);
+ }
+ }
+
+ if (!ids.isEmpty()) {
+ notificationService.post(new WaveformChangeEvent(ids).setAddOrUpdate(true));
+ }
+ return ids;
+ }
+
+ private List findIdsByPolygonAndActiveStatus(List geoJSON, boolean inside, boolean active) {
+ List selectedWaveformIds = new ArrayList<>();
+ if (geoJSON != null && !geoJSON.isEmpty()) {
+ try {
+ FeatureCollection featureCollection = (FeatureCollection) GeoJSONFactory.create(geoJSON.get(0).getRawGeoJson());
+
+ GeoJSONReader reader = new GeoJSONReader();
+
+ //Combine the geometries
+ List geoms = new ArrayList<>();
+ for (Feature feature : featureCollection.getFeatures()) {
+ geoms.add(reader.read(feature.getGeometry()));
+ }
+
+ Geometry geo = GeometryCombiner.combine(geoms);
+
+ Geometry bounds = geo.getEnvelope();
+ //minx miny, maxx miny, maxx maxy, minx maxy, minx miny
+ if (bounds.getNumPoints() == 5) {
+ IndexedPointInAreaLocator locator = new IndexedPointInAreaLocator(geo);
+ Coordinate[] coords = bounds.getCoordinates();
+
+ //Test for polygon intersection and drop any that fail
+ List possibleWaveforms;
+ BiFunction test;
+ if (inside) {
+ possibleWaveforms = waveformRepository.getMetadataInsideBounds(active,
+ Math.min(coords[0].getY(), coords[2].getY()),
+ Math.min(coords[0].getX(), coords[2].getX()),
+ Math.max(coords[0].getY(), coords[2].getY()),
+ Math.max(coords[0].getX(), coords[2].getX()));
+ test = (resEv, resSta) -> resEv != Location.EXTERIOR || resSta != Location.EXTERIOR;
+ } else {
+ possibleWaveforms = waveformRepository.getWaveformMetadataByActive(active);
+ test = (resEv, resSta) -> resEv == Location.EXTERIOR && resSta == Location.EXTERIOR;
+ }
+
+ selectedWaveformIds.addAll(possibleWaveforms.stream().filter(w -> {
+ int resEv = locator.locate(new Coordinate(w.getEvent().getLongitude(), w.getEvent().getLatitude()));
+ int resSta = locator.locate(new Coordinate(w.getStream().getStation().getLongitude(), w.getStream().getStation().getLatitude()));
+ return test.apply(resEv, resSta);
+ }).map(w -> w.getId()).collect(Collectors.toList()));
+ }
+ } catch (RuntimeException ex) {
+ log.error(ex.getLocalizedMessage());
+ }
+
+ }
+ return selectedWaveformIds;
+ }
+}
diff --git a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/MdacCalculatorService.java b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/MdacCalculatorService.java
index 26f78257..a3e0ccea 100644
--- a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/MdacCalculatorService.java
+++ b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/MdacCalculatorService.java
@@ -129,4 +129,8 @@ public double getMwInDyne(double testMw) {
public double getCornerFrequency(Function mdacFunc) {
return mdacFunc.apply(Double.valueOf(1.0))[MdacCalculator.ANGULAR_CORNER_FREQ_IDX] / (Math.PI * 2.0);
}
+
+ public double getCornerFrequency(MdacParametersPS mdacPs, MdacParametersFI stress, double mw) {
+ return getCornerFrequency(getCalculateMdacSourceSpectraFunction(mdacPs, stress, mw));
+ }
}
diff --git a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/SpectraCalculator.java b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/SpectraCalculator.java
index 8425dea9..977e0898 100644
--- a/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/SpectraCalculator.java
+++ b/calibration-service/calibration-service-impl/src/main/java/gov/llnl/gnem/apps/coda/calibration/service/impl/processing/SpectraCalculator.java
@@ -443,7 +443,7 @@ public Spectra computeFitSpectra(MeasuredMwParameters event, Collection bands, PICK_TYPES selectedPhase, SPECTRA_TYPES type) {
- MdacParametersFI mdacFiEntry = mdacFiService.findFirst();
+ MdacParametersFI mdacFiEntry = new MdacParametersFI(mdacFiService.findFirst());
MdacParametersPS psRows = mdacPsService.findMatchingPhase(selectedPhase.getPhase());
List xyPoints = new ArrayList<>();
@@ -454,7 +454,11 @@ public Spectra computeSpecificSpectra(Double mw, Double apparentStress, Collecti
}
Function mdacFunction = mdacService.getCalculateMdacAmplitudeForMwFunction(psRows, mdacFiEntry, mw, selectedPhase);
+ double cornerFrequency = -1;
+ if (type != null && type.equals(SPECTRA_TYPES.FIT)) {
+ cornerFrequency = mdacService.getCornerFrequency(psRows, mdacFiEntry.setPsi(0.0).setSigma(apparentStress), mw);
+ }
for (FrequencyBand band : bands) {
double centerFreq = band.getLowFrequency() + (band.getHighFrequency() - band.getLowFrequency()) / 2.;
double logFreq = Math.log10(centerFreq);
@@ -467,7 +471,7 @@ public Spectra computeSpecificSpectra(Double mw, Double apparentStress, Collecti
}
}
Collections.sort(xyPoints, (p1, p2) -> Double.compare(p1.getX(), p2.getX()));
- return new Spectra(type, xyPoints, mw, apparentStress);
+ return new Spectra(type, xyPoints, mw, apparentStress, cornerFrequency);
}
/**
@@ -572,7 +576,7 @@ public double value(double[] point) {
}
double fit = WCVRMSD(weightMap, dataMap);
- double corner = mdacService.getCornerFrequency(mdacService.getCalculateMdacSourceSpectraFunction(mdacPs, mdacFi.setPsi(0.0).setSigma(testSigma), testMw));
+ double corner = mdacService.getCornerFrequency(mdacService.getCalculateMdacSourceSpectraFunction(mdacPs, new MdacParametersFI(mdacFi).setPsi(0.0).setSigma(testSigma), testMw));
stats.addValue(new double[] { testMw, testSigma, fit, corner });
optimizerMeasurements.add(new ImmutableTriple<>(fit, testMw, testSigma));
return fit;
@@ -606,7 +610,7 @@ public double value(double[] point) {
for (double mw = minMW; mw < maxMW; mw = mw + ((maxMW - minMW) / 100.)) {
for (double stress = minApparentStress; stress < maxApparentStress; stress = stress + ((maxApparentStress - minApparentStress) / 100.)) {
double res = mdacFunction.value(new double[] { mw, stress });
- double corner = mdacService.getCornerFrequency(mdacService.getCalculateMdacSourceSpectraFunction(mdacPs, mdacFi.setPsi(0.0).setSigma(stress), mw));
+ double corner = mdacService.getCornerFrequency(mdacPs, mdacFi.setPsi(0.0).setSigma(stress), mw);
stats.addValue(new double[] { mw, stress, res, corner });
optimizerMeasurements.add(new ImmutableTriple<>(res, mw, stress));
if (res < best) {
@@ -692,7 +696,7 @@ public double value(double[] point) {
result[APP_2_MIN] = result[APP_STRESS];
result[APP_2_MAX] = result[APP_STRESS];
}
- result[CORNER_FREQ] = mdacService.getCornerFrequency(mdacService.getCalculateMdacSourceSpectraFunction(mdacPs, mdacFi.setPsi(0.0).setSigma(result[APP_STRESS]), result[MW_FIT]));
+ result[CORNER_FREQ] = mdacService.getCornerFrequency(mdacService.getCalculateMdacSourceSpectraFunction(mdacPs, new MdacParametersFI(mdacFi).setPsi(0.0).setSigma(result[APP_STRESS]), result[MW_FIT]));
result[ITR_COUNT] = iterations;
return result;
}
diff --git a/calibration-service/calibration-service-impl/src/test/java/gov/llnl/gnem/apps/coda/calibration/service/impl/GeometryServiceImplTest.java b/calibration-service/calibration-service-impl/src/test/java/gov/llnl/gnem/apps/coda/calibration/service/impl/GeometryServiceImplTest.java
new file mode 100644
index 00000000..650c5c1e
--- /dev/null
+++ b/calibration-service/calibration-service-impl/src/test/java/gov/llnl/gnem/apps/coda/calibration/service/impl/GeometryServiceImplTest.java
@@ -0,0 +1,200 @@
+/*
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* CODE-743439.
+* All rights reserved.
+* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
+*
+* Licensed under the Apache License, Version 2.0 (the “Licensee”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
+* http://www.apache.org/licenses/LICENSE-2.0
+* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and limitations under the license.
+*
+* This work was performed under the auspices of the U.S. Department of Energy
+* by Lawrence Livermore National Laboratory under Contract DE-AC52-07NA27344.
+*/
+package gov.llnl.gnem.apps.coda.calibration.service.impl;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.ArrayUtils;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gov.llnl.gnem.apps.coda.calibration.model.domain.GeoJsonPolygon;
+import gov.llnl.gnem.apps.coda.calibration.repository.PolygonRepository;
+import gov.llnl.gnem.apps.coda.common.model.domain.Event;
+import gov.llnl.gnem.apps.coda.common.model.domain.Station;
+import gov.llnl.gnem.apps.coda.common.model.domain.Stream;
+import gov.llnl.gnem.apps.coda.common.model.domain.Waveform;
+import gov.llnl.gnem.apps.coda.common.repository.WaveformRepository;
+import gov.llnl.gnem.apps.coda.common.service.api.NotificationService;
+
+@ExtendWith(MockitoExtension.class)
+public class GeometryServiceImplTest {
+
+ private final Logger log = LoggerFactory.getLogger(this.getClass());
+
+ @InjectMocks
+ private GeometryServiceImpl geometryService;
+
+ @Mock
+ private WaveformRepository waveformRepository;
+
+ @Mock
+ private PolygonRepository polygonRepository;
+
+ @Mock
+ private NotificationService notificationService;
+
+ private List waveforms = new ArrayList<>();
+
+ private List polygons = new ArrayList<>();
+
+ @BeforeEach
+ protected void setUp() throws Exception {
+ Waveform w1 = createWaveform();
+ w1.setId(0l);
+ w1.setActive(false);
+ w1.getEvent().setLatitude(-2.0);
+ w1.getEvent().setLongitude(-2.0);
+ w1.getStream().getStation().setLatitude(-1.0);
+ w1.getStream().getStation().setLongitude(-1.0);
+ waveforms.add(w1);
+
+ Waveform w2 = createWaveform();
+ w2.setId(1l);
+ w2.setActive(true);
+ w2.getEvent().setEventId("2345");
+ w2.getEvent().setLatitude(-2.0);
+ w2.getEvent().setLongitude(2.0);
+ w2.getStream().getStation().setLatitude(-1.0);
+ w2.getStream().getStation().setLongitude(1.0);
+ waveforms.add(w2);
+
+ Waveform w3 = createWaveform();
+ w3.setId(2l);
+ w3.setActive(true);
+ w3.getStream().getStation().setStationName("TEST2");
+ w3.getEvent().setLatitude(2.0);
+ w3.getEvent().setLongitude(-2.0);
+ w3.getStream().getStation().setLatitude(1.0);
+ w3.getStream().getStation().setLongitude(-1.0);
+ waveforms.add(w3);
+
+ Waveform w4 = createWaveform();
+ w4.setId(3l);
+ w4.setActive(false);
+ w4.getEvent().setEventId("2345");
+ w4.getStream().getStation().setStationName("TEST2");
+ w4.getEvent().setLatitude(2.0);
+ w4.getEvent().setLongitude(2.0);
+ w4.getStream().getStation().setLatitude(1.0);
+ w4.getStream().getStation().setLongitude(1.0);
+ waveforms.add(w4);
+
+ polygons.add(new GeoJsonPolygon().setRawGeoJson("{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[-3.0,-3.0],[3.0,-3.0],[3.0,0.0],[-3.0,0.0],[-3.0,-3.0]]]}}]}"));
+ Mockito.when(polygonRepository.findAll()).thenReturn(polygons);
+
+ Mockito.when(waveformRepository.setActiveIn(Mockito.anyBoolean(), Mockito.anyList()))
+ .thenAnswer(invocation -> {
+ boolean active = (boolean) invocation.getArgument(0);
+ List ids = (List) invocation.getArgument(1);
+ List selectedWaveforms = waveforms.stream().filter(w -> ids.contains(w.getId())).collect(Collectors.toList());
+ selectedWaveforms.forEach(w->w.setActive(active));
+ return selectedWaveforms.size();
+ });
+ }
+
+ @AfterEach
+ protected void tearDown() throws Exception {
+ waveforms.clear();
+ }
+
+ @Test
+ public void testExcludeInside() throws Exception {
+ testInside(false);
+ }
+
+ @Test
+ public void testIncludeInside() throws Exception {
+ testInside(true);
+ }
+
+ private void testInside(boolean active) {
+ Mockito.when(waveformRepository.getMetadataInsideBounds(Mockito.anyBoolean(), Mockito.anyDouble(), Mockito.anyDouble(), Mockito.anyDouble(), Mockito.anyDouble())).thenReturn(waveforms);
+ List ids = geometryService.setActiveFlagInsidePolygon(active);
+ List activeIds = waveforms.stream().filter(w -> w.getActive() == active).map(w -> w.getId()).collect(Collectors.toList());
+
+ Assertions.assertArrayEquals(new long[] { 0l, 1l }, ArrayUtils.toPrimitive(ids.toArray(new Long[0])), "Expecting the first and second waveforms to toggle their active status.");
+ Assertions.assertTrue(activeIds.containsAll(ids), "Expecting the included/excluded waveform list to contain the selected ids");
+ }
+
+ @Test
+ public void testExcludeOutside() throws Exception {
+ testOutside(false, 2l);
+ }
+
+ @Test
+ public void testIncludeOutside() throws Exception {
+ testOutside(true, 3l);
+ }
+
+ private void testOutside(boolean active, long... expectedIds) {
+ Mockito.when(waveformRepository.getWaveformMetadataByActive(Mockito.anyBoolean()))
+ .then(invocation -> waveforms.stream().filter(w -> w.getActive() == (boolean) invocation.getArgument(0)).collect(Collectors.toList()));
+
+ List ids = geometryService.setActiveFlagOutsidePolygon(active);
+ List activeIds = waveforms.stream().filter(w -> w.getActive() == active).map(w -> w.getId()).collect(Collectors.toList());
+ Assertions.assertArrayEquals(expectedIds, ArrayUtils.toPrimitive(ids.toArray(new Long[0])));
+ Assertions.assertTrue(activeIds.containsAll(ids), "Expecting the included/excluded waveform list to contain the selected ids");
+ }
+
+ private Waveform createWaveform() {
+ Date startTime = Date.from(Instant.now());
+ Date endTime = Date.from(startTime.toInstant().plusSeconds(1l));
+
+ Event event = new Event();
+ event.setEventId("1234");
+ event.setLatitude(1.0);
+ event.setLongitude(1.0);
+
+ Station station = new Station();
+ station.setLatitude(1.0);
+ station.setLongitude(1.0);
+ station.setStationName("TEST");
+ station.setNetworkName(null);
+
+ Stream s1 = new Stream();
+ s1.setChannelName("BHE");
+ s1.setStation(station);
+
+ double[] data = new double[400];
+ Arrays.fill(data, 0, 200, 1000.0);
+ Arrays.fill(data, 2, 400, 2000.0);
+ Waveform w1 = new Waveform();
+ w1.setEvent(event);
+ w1.setStream(s1);
+ w1.setSegment(data);
+ w1.setBeginTime(startTime);
+ w1.setEndTime(endTime);
+ w1.setSampleRate(16d);
+ w1.setLowFrequency(0d);
+ w1.setHighFrequency(1d);
+ return w1;
+ }
+
+}
diff --git a/calibration-service/pom.xml b/calibration-service/pom.xml
index 2e05cae8..afe55f4f 100644
--- a/calibration-service/pom.xml
+++ b/calibration-service/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/calibration-standalone/pom.xml b/calibration-standalone/pom.xml
index 8068f722..3d5512d0 100644
--- a/calibration-standalone/pom.xml
+++ b/calibration-standalone/pom.xml
@@ -6,7 +6,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/calibration-standalone/src/main/java/gov/llnl/gnem/apps/coda/calibration/standalone/data/client/ParameterLocalClient.java b/calibration-standalone/src/main/java/gov/llnl/gnem/apps/coda/calibration/standalone/data/client/ParameterLocalClient.java
index d625310c..ebfb6654 100644
--- a/calibration-standalone/src/main/java/gov/llnl/gnem/apps/coda/calibration/standalone/data/client/ParameterLocalClient.java
+++ b/calibration-standalone/src/main/java/gov/llnl/gnem/apps/coda/calibration/standalone/data/client/ParameterLocalClient.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -17,8 +17,6 @@
import java.util.List;
import java.util.Optional;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@@ -45,8 +43,6 @@
@Primary
public class ParameterLocalClient implements ParameterClient {
- private static final Logger log = LoggerFactory.getLogger(ParameterLocalClient.class);
-
private SharedFrequencyBandParametersService sharedParamsService;
private SiteFrequencyBandParametersService siteParamsService;
private MdacParametersFiService mdacFiService;
@@ -145,5 +141,15 @@ public Mono getShapeFitterConstraints() {
public Mono updateShapeFitterConstraints(ShapeFitterConstraints conf) {
return Mono.just(Optional.ofNullable(configService.update(conf)).map(v -> v.toString()).orElseGet(() -> ""));
}
+
+ @Override
+ public Mono updateMapPolygon(String rawGeoJSON) {
+ return Mono.just(configService.updatePolygon(rawGeoJSON)).onErrorReturn("");
+ }
+
+ @Override
+ public Mono getMapPolygon() {
+ return Mono.just(configService.getPolygonGeoJSON()).onErrorReturn("");
+ }
}
diff --git a/calibration-standalone/src/main/java/gov/llnl/gnem/apps/coda/calibration/standalone/data/client/WaveformLocalClient.java b/calibration-standalone/src/main/java/gov/llnl/gnem/apps/coda/calibration/standalone/data/client/WaveformLocalClient.java
index 9adb9834..106d8f84 100644
--- a/calibration-standalone/src/main/java/gov/llnl/gnem/apps/coda/calibration/standalone/data/client/WaveformLocalClient.java
+++ b/calibration-standalone/src/main/java/gov/llnl/gnem/apps/coda/calibration/standalone/data/client/WaveformLocalClient.java
@@ -24,6 +24,7 @@
import com.fasterxml.jackson.core.JsonProcessingException;
+import gov.llnl.gnem.apps.coda.calibration.service.api.GeometryService;
import gov.llnl.gnem.apps.coda.calibration.service.api.SyntheticService;
import gov.llnl.gnem.apps.coda.common.gui.data.client.api.WaveformClient;
import gov.llnl.gnem.apps.coda.common.model.domain.SyntheticCoda;
@@ -36,13 +37,15 @@
@Primary
public class WaveformLocalClient implements WaveformClient {
- private WaveformService service;
+ private WaveformService service;
private SyntheticService synthService;
+ private GeometryService geometryService;
@Autowired
- public WaveformLocalClient(WaveformService service, SyntheticService synthService) {
+ public WaveformLocalClient(WaveformService service, SyntheticService synthService, GeometryService geometryService) {
this.service = service;
this.synthService = synthService;
+ this.geometryService = geometryService;
}
@Override
@@ -110,4 +113,13 @@ public Flux setWaveformsActiveByStationName(String id, boolean active) {
return Flux.just(service.setActiveFlagByStationName(id, active).toString());
}
+ @Override
+ public Flux setWaveformsActiveOutsidePolygon(boolean active) {
+ return Flux.just(geometryService.setActiveFlagOutsidePolygon(active).toString());
+ }
+
+ @Override
+ public Flux setWaveformsActiveInsidePolygon(boolean active) {
+ return Flux.just(geometryService.setActiveFlagInsidePolygon(active).toString());
+ }
}
diff --git a/calibration-standalone/src/test/java/gov/llnl/gnem/apps/coda/calibration/AssessAutopicker.java b/calibration-standalone/src/test/java/gov/llnl/gnem/apps/coda/calibration/AssessAutopicker.java
index 645c0ea1..ba2e2b1a 100644
--- a/calibration-standalone/src/test/java/gov/llnl/gnem/apps/coda/calibration/AssessAutopicker.java
+++ b/calibration-standalone/src/test/java/gov/llnl/gnem/apps/coda/calibration/AssessAutopicker.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -27,7 +27,7 @@
import java.util.stream.Stream;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
-import org.junit.Assert;
+import org.junit.jupiter.api.Assertions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,13 +61,12 @@ public static void main(String[] args) {
}
List waveforms = loader.convertFiles(files)
- .doOnError(error -> Assert.fail(error.getMessage()))
+ .doOnError(error -> Assertions.fail(error.getMessage()))
.filter(Objects::nonNull)
.filter(r -> r.getResultPayload() != null && r.getResultPayload().isPresent())
.map(r -> r.getResultPayload().get())
- .filter(
- w -> w.getAssociatedPicks() != null
- && w.getAssociatedPicks().stream().filter(pick -> PICK_TYPES.F.getPhase().equalsIgnoreCase(pick.getPickType())).findAny().isPresent())
+ .filter(w -> w.getAssociatedPicks() != null
+ && w.getAssociatedPicks().stream().filter(pick -> PICK_TYPES.F.getPhase().equalsIgnoreCase(pick.getPickType())).findAny().isPresent())
.collectList()
.block(Duration.ofSeconds(10l));
@@ -79,15 +78,14 @@ public static void main(String[] args) {
Double maxTime = halfSeries.getMaxTime()[0];
double startTime = series.getTime().getEpochTime() + maxTime;
- double stopTime = picker.getEndTime(
- series.getData(),
- series.getSamprate(),
- startTime,
- series.getIndexForTime(startTime),
- 0,
- 1200,
- 0.0,
- WaveformUtils.getNoiseFloor(WaveformUtils.floatsToDoubles(series.getData())));
+ double stopTime = picker.getEndTime(series.getData(),
+ series.getSamprate(),
+ startTime,
+ series.getIndexForTime(startTime),
+ 0,
+ 1200,
+ 0.0,
+ WaveformUtils.getNoiseFloor(WaveformUtils.floatsToDoubles(series.getData())));
if (new TimeT(stopTime).gt(new TimeT(startTime))) {
stopTime = stopTime + series.getTime().subtractD(new TimeT(w.getEvent().getOriginTime()));
}
diff --git a/common-gui/pom.xml b/common-gui/pom.xml
index af8bbc27..f082abe4 100644
--- a/common-gui/pom.xml
+++ b/common-gui/pom.xml
@@ -7,7 +7,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
gov.llnl.gnem.apps.coda.common
diff --git a/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/data/client/WaveformWebClient.java b/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/data/client/WaveformWebClient.java
index c24e99b8..eab9e0b8 100644
--- a/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/data/client/WaveformWebClient.java
+++ b/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/data/client/WaveformWebClient.java
@@ -175,4 +175,24 @@ public Flux setWaveformsActiveByStationName(String id, boolean active) {
.exchange()
.flatMapMany(resp -> Flux.just(resp.toString()));
}
+
+ @Override
+ public Flux setWaveformsActiveOutsidePolygon(boolean active) {
+ return client.post()
+ .uri("/geometry/set-active/waveforms-outside-polygon/" + active)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .flatMapMany(resp -> Flux.just(resp.toString()));
+ }
+
+ @Override
+ public Flux setWaveformsActiveInsidePolygon(boolean active) {
+ return client.post()
+ .uri("/geometry/set-active/waveforms-inside-polygon/" + active)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .flatMapMany(resp -> Flux.just(resp.toString()));
+ }
}
diff --git a/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/data/client/api/WaveformClient.java b/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/data/client/api/WaveformClient.java
index 13d7bd8f..be367763 100644
--- a/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/data/client/api/WaveformClient.java
+++ b/common-gui/src/main/java/gov/llnl/gnem/apps/coda/common/gui/data/client/api/WaveformClient.java
@@ -51,4 +51,8 @@ public interface WaveformClient {
public Flux setWaveformsActiveByEventId(String id, boolean active);
public Flux setWaveformsActiveByStationName(String id, boolean active);
+
+ public Flux setWaveformsActiveOutsidePolygon(boolean active);
+
+ public Flux setWaveformsActiveInsidePolygon(boolean active);
}
diff --git a/common-gui/src/test/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacExporterTest.java b/common-gui/src/test/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacExporterTest.java
index 4809c73d..c667f5bb 100644
--- a/common-gui/src/test/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacExporterTest.java
+++ b/common-gui/src/test/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacExporterTest.java
@@ -20,19 +20,15 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Date;
-import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
-import java.util.Locale;
import java.util.function.Consumer;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import org.junit.Assert;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -111,7 +107,7 @@ public void testWriteWaveformToDirectory(Waveform input, ArgumentsAccessor argum
@MethodSource("testParamSet")
public void testGetFileName(Waveform input, String expectedFilename) throws Exception {
String actual = exporter.getFileName(input);
- Assert.assertEquals(expectedFilename, actual);
+ Assertions.assertEquals(expectedFilename, actual);
}
@Test
@@ -119,31 +115,31 @@ public void testEventDepthPopulated() throws Exception {
//GMPAPPS-1947 Envelope tool was dropping event depth info during import/export.
Waveform waveform = createValidWaveform();
SACHeader header = exporter.sacHeaderFromWaveform(waveform);
- Assert.assertTrue("Expect that the waveform should have a populated event depth if the original file had it.", header.evdp != 0 && !SACHeader.isDefault(header.evdp));
+ Assertions.assertTrue(header.evdp != 0 && !SACHeader.isDefault(header.evdp), "Expect that the waveform should have a populated event depth if the original file had it.");
}
private static Consumer> waveformNotValidAssertions() throws Exception {
return res -> {
- Assert.assertFalse("Result on an invalid waveform should be false", res.isSuccess());
+ Assertions.assertFalse(res.isSuccess(), "Result on an invalid waveform should be false");
try {
java.util.stream.Stream stream = Files.list(testDir.toPath());
- Assert.assertFalse("Files should never be created for an invalid waveform", stream.findFirst().isPresent());
+ Assertions.assertFalse(stream.findFirst().isPresent(), "Files should never be created for an invalid waveform");
stream.close();
} catch (IOException e) {
- Assert.fail("Unable to list the contents of the test directory: " + testDir.getAbsolutePath() + " : " + e.toString());
+ Assertions.fail("Unable to list the contents of the test directory: " + testDir.getAbsolutePath() + " : " + e.toString());
}
};
}
private static Consumer> waveformValidAssertions() {
return res -> {
- Assert.assertTrue("Result on an valid waveform should be true: " + res.getResultPayload().get(), res.isSuccess());
+ Assertions.assertTrue(res.isSuccess(), "Result on an valid waveform should be true: " + res.getResultPayload().get());
Path filePath = testDir.toPath().resolve(res.getResultPayload().get());
- Assert.assertTrue("File should be created for valid waveforms", Files.exists(filePath));
+ Assertions.assertTrue(Files.exists(filePath), "File should be created for valid waveforms");
try {
Files.delete(filePath);
} catch (IOException e) {
- Assert.fail("Temporary files should never exist after a test is complete but an error occured during deletion: " + e.toString());
+ Assertions.fail("Temporary files should never exist after a test is complete but an error occured during deletion: " + e.toString());
}
};
}
diff --git a/common-gui/src/test/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacLoaderTest.java b/common-gui/src/test/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacLoaderTest.java
index 9470c52b..fe80b2eb 100644
--- a/common-gui/src/test/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacLoaderTest.java
+++ b/common-gui/src/test/java/gov/llnl/gnem/apps/coda/common/gui/converters/sac/SacLoaderTest.java
@@ -27,8 +27,8 @@
import java.util.stream.IntStream;
import java.util.stream.Stream;
-import org.junit.Assert;
import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -60,10 +60,10 @@ public void teardown() {
@ParameterizedTest
@MethodSource("singleFile")
public void testConvertFile(File inputFile) throws Exception {
- Result res = loader.convertFile(inputFile).doOnError(error -> Assert.fail(error.getMessage())).block(Duration.ofSeconds(10l));
- Assert.assertTrue("Expect that waveform results should all complete successfully", res.isSuccess());
- Assert.assertTrue("Expect that waveform results should have no error or warning messages", res.getErrors().isEmpty());
- Assert.assertTrue("Expect that waveform results should have a Waveform payload", res.getResultPayload().isPresent());
+ Result res = loader.convertFile(inputFile).doOnError(error -> Assertions.fail(error.getMessage())).block(Duration.ofSeconds(10l));
+ Assertions.assertTrue(res.isSuccess(), "Expect that waveform results should all complete successfully");
+ Assertions.assertTrue(res.getErrors().isEmpty(), "Expect that waveform results should have no error or warning messages");
+ Assertions.assertTrue(res.getResultPayload().isPresent(), "Expect that waveform results should have a Waveform payload");
}
public static Collection singleFile() throws IOException {
@@ -84,11 +84,11 @@ public void testConvertFiles() throws Exception {
return null;
}
}).filter(o -> o != null).collect(Collectors.toList());
- List> results = loader.convertFiles(multipleFiles.get(0)).doOnError(error -> Assert.fail(error.getMessage())).collectList().block(Duration.ofSeconds(10l));
+ List> results = loader.convertFiles(multipleFiles.get(0)).doOnError(error -> Assertions.fail(error.getMessage())).collectList().block(Duration.ofSeconds(10l));
for (Result res : results) {
- Assert.assertTrue("Expect that waveform results should all complete successfully", res.isSuccess());
- Assert.assertTrue("Expect that waveform results should have no error or warning messages", res.getErrors().isEmpty());
- Assert.assertTrue("Expect that waveform results should have a Waveform payload", res.getResultPayload().isPresent());
+ Assertions.assertTrue(res.isSuccess(), "Expect that waveform results should all complete successfully");
+ Assertions.assertTrue(res.getErrors().isEmpty(), "Expect that waveform results should have no error or warning messages");
+ Assertions.assertTrue(res.getResultPayload().isPresent(), "Expect that waveform results should have a Waveform payload");
}
}
@@ -103,9 +103,9 @@ public void testEventDepthPopulated() throws Exception {
return null;
}
}).filter(o -> o != null).collect(Collectors.toList());
- List> results = loader.convertFiles(multipleFiles.get(0)).doOnError(error -> Assert.fail(error.getMessage())).collectList().block(Duration.ofSeconds(10l));
+ List> results = loader.convertFiles(multipleFiles.get(0)).doOnError(error -> Assertions.fail(error.getMessage())).collectList().block(Duration.ofSeconds(10l));
for (Result res : results) {
- Assert.assertTrue("Expect that the waveform should have a populated event depth if the original file had it.", res.getResultPayload().get().getEvent().getDepth() != 0);
+ Assertions.assertTrue(res.getResultPayload().get().getEvent().getDepth() != 0, "Expect that the waveform should have a populated event depth if the original file had it.");
}
}
}
diff --git a/common-service/common-application/pom.xml b/common-service/common-application/pom.xml
index ec7dbdbe..71a7b649 100644
--- a/common-service/common-application/pom.xml
+++ b/common-service/common-application/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.common
common-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/common-service/common-application/src/main/java/gov/llnl/gnem/apps/coda/common/application/config/WebSocketConfig.java b/common-service/common-application/src/main/java/gov/llnl/gnem/apps/coda/common/application/config/WebSocketConfig.java
index 1c96c5bd..43c1c1bb 100644
--- a/common-service/common-application/src/main/java/gov/llnl/gnem/apps/coda/common/application/config/WebSocketConfig.java
+++ b/common-service/common-application/src/main/java/gov/llnl/gnem/apps/coda/common/application/config/WebSocketConfig.java
@@ -27,9 +27,10 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
- registry.addEndpoint("/websocket-guide").setAllowedOrigins("*").withSockJS();
+ registry.addEndpoint("/websocket-guide").withSockJS();
}
+
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue/", "/topic/").setTaskScheduler(new DefaultManagedTaskScheduler());
diff --git a/common-service/common-application/src/test/java/gov/llnl/gnem/apps/coda/common/util/NumberFormatFactoryTest.java b/common-service/common-application/src/test/java/gov/llnl/gnem/apps/coda/common/util/NumberFormatFactoryTest.java
index 12d1f278..a96568e7 100644
--- a/common-service/common-application/src/test/java/gov/llnl/gnem/apps/coda/common/util/NumberFormatFactoryTest.java
+++ b/common-service/common-application/src/test/java/gov/llnl/gnem/apps/coda/common/util/NumberFormatFactoryTest.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -20,7 +20,7 @@
import java.util.Collection;
import java.util.List;
-import org.junit.Assert;
+import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.aggregator.ArgumentsAccessor;
import org.junit.jupiter.params.provider.MethodSource;
@@ -34,7 +34,7 @@ public final void testTwoDecimalOneLeadingZeroFormattingExpectations(Number inpu
String expectedTwoDigit = args.getString(1);
NumberFormat formatter = NumberFormatFactory.twoDecimalOneLeadingZero();
String actual = formatter.format(input);
- Assert.assertEquals(expectedTwoDigit, actual);
+ Assertions.assertEquals(expectedTwoDigit, actual);
}
@ParameterizedTest
@@ -43,7 +43,7 @@ public final void testFourDecimalOneLeadingZeroFormattingExpectations(Number inp
String expectedFourDigit = args.getString(2);
NumberFormat formatter = NumberFormatFactory.fourDecimalOneLeadingZero();
String actual = formatter.format(input);
- Assert.assertEquals(expectedFourDigit, actual);
+ Assertions.assertEquals(expectedFourDigit, actual);
}
@SuppressWarnings("unused")
diff --git a/common-service/common-model/pom.xml b/common-service/common-model/pom.xml
index 6497be2f..62032946 100644
--- a/common-service/common-model/pom.xml
+++ b/common-service/common-model/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.common
common-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/common-service/common-repository/pom.xml b/common-service/common-repository/pom.xml
index 330ea915..79d76f44 100644
--- a/common-service/common-repository/pom.xml
+++ b/common-service/common-repository/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.common
common-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/common-service/common-repository/src/main/java/gov/llnl/gnem/apps/coda/common/repository/WaveformRepository.java b/common-service/common-repository/src/main/java/gov/llnl/gnem/apps/coda/common/repository/WaveformRepository.java
index 0f5eae6a..a5050665 100644
--- a/common-service/common-repository/src/main/java/gov/llnl/gnem/apps/coda/common/repository/WaveformRepository.java
+++ b/common-service/common-repository/src/main/java/gov/llnl/gnem/apps/coda/common/repository/WaveformRepository.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -28,7 +28,6 @@
import gov.llnl.gnem.apps.coda.common.model.domain.Stream;
import gov.llnl.gnem.apps.coda.common.model.domain.Waveform;
import gov.llnl.gnem.apps.coda.common.model.domain.WaveformPick;
-import gov.llnl.gnem.apps.coda.common.repository.DetachableJpaRepository;
@Transactional
public interface WaveformRepository extends DetachableJpaRepository {
@@ -43,6 +42,9 @@ public Waveform findOneByAllFields(@Param("beginTime") Date beginTime, @Param("e
@Query("select new Waveform(w.id, w.version, w.event, w.stream, w.beginTime, w.endTime, w.segmentType, w.segmentUnits, w.lowFrequency, w.highFrequency, w.sampleRate, w.active) from Waveform w order by w.id desc")
public Set getWaveformMetadata();
+
+ @Query("select new Waveform(w.id, w.version, w.event, w.stream, w.beginTime, w.endTime, w.segmentType, w.segmentUnits, w.lowFrequency, w.highFrequency, w.sampleRate, w.active) from Waveform w where w.active = :active order by w.id desc")
+ public List getWaveformMetadataByActive(@Param("active") boolean active);
@Query("select new Waveform(w.id, w.version, w.event, w.stream, w.beginTime, w.endTime, w.segmentType, w.segmentUnits, w.lowFrequency, w.highFrequency, w.sampleRate, w.active) from Waveform w where w.id in :ids order by w.id desc")
public List findAllMetadataByIds(@Param("ids") List ids);
@@ -64,6 +66,26 @@ public Waveform findOneByAllFields(@Param("beginTime") Date beginTime, @Param("e
@Query("update Waveform w SET w.active = :active where w.stream.station.stationName = :stationName")
public int setActiveByStationName(@Param("stationName") String stationName, @Param("active") boolean active);
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query("update Waveform w SET w.active = :active")
+ public void setAllActive(boolean active);
+
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query("update Waveform w SET w.active = :active where w.id in (:ids)")
+ public int setActiveIn(@Param("active") boolean active, @Param("ids") List waveformIds);
+
+ @Modifying(clearAutomatically = true, flushAutomatically = true)
+ @Query("update Waveform w SET w.active = :active where w.id not in (:ids)")
+ public int setActiveNotIn(@Param("active") boolean active, @Param("ids") List waveformIds);
+
+ @Query("select new Waveform(w.id, w.version, w.event, w.stream, w.beginTime, w.endTime, w.segmentType, w.segmentUnits, w.lowFrequency, w.highFrequency, w.sampleRate, w.active) from Waveform w "
+ + "where w.active = :active and"
+ + "(w.stream.station.latitude between :minX and :maxX "
+ + "and w.stream.station.longitude between :minY and :maxY) "
+ + "or (w.event.latitude between :minX and :maxX "
+ + "and w.event.longitude between :minY and :maxY)")
+ public List getMetadataInsideBounds(@Param("active") boolean active, @Param("minX") Double minX, @Param("minY") Double minY, @Param("maxX") Double maxX, @Param("maxY") Double maxY);
+
@Query("select w.id from Waveform w where w.event.eventId = :eventId")
public List findAllIdsByEventId(@Param("eventId") String eventId);
@@ -76,4 +98,9 @@ public Waveform findOneByAllFields(@Param("beginTime") Date beginTime, @Param("e
@Query("select w from Waveform w where w.active = true and w.event.eventId = :eventId and w.stream.channelName = 'STACK' and w.stream.station.stationName in :stationNames")
public List findAllActiveStacksByEventIdAndStationNames(@Param("eventId") String eventId, @Param("stationNames") List stationNames);
+ @Query("select w.id from Waveform w where w.active = false")
+ public List findAllInactiveIds();
+
+ @Query("select w.id from Waveform w where w.id not in (:ids)")
+ public List findIdsNotIn(@Param("ids") List ids);
}
diff --git a/common-service/common-service-api/pom.xml b/common-service/common-service-api/pom.xml
index 96dc89ba..23a7a55f 100644
--- a/common-service/common-service-api/pom.xml
+++ b/common-service/common-service-api/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.common
common-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/common-service/common-service-impl/pom.xml b/common-service/common-service-impl/pom.xml
index f401e5ac..be38ea52 100644
--- a/common-service/common-service-impl/pom.xml
+++ b/common-service/common-service-impl/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.common
common-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/common-service/common-service-impl/src/main/java/gov/llnl/gnem/apps/coda/common/service/impl/WaveformServiceImpl.java b/common-service/common-service-impl/src/main/java/gov/llnl/gnem/apps/coda/common/service/impl/WaveformServiceImpl.java
index 56302a65..129285d8 100644
--- a/common-service/common-service-impl/src/main/java/gov/llnl/gnem/apps/coda/common/service/impl/WaveformServiceImpl.java
+++ b/common-service/common-service-impl/src/main/java/gov/llnl/gnem/apps/coda/common/service/impl/WaveformServiceImpl.java
@@ -44,7 +44,7 @@
@Service
public class WaveformServiceImpl implements WaveformService {
- private WaveformRepository waveformRepository;
+ private WaveformRepository waveformRepository;
private NotificationService notificationService;
private ExampleMatcher ignoreStandardFieldsMatcher = ExampleMatcher.matching().withIgnoreNullValues().withIgnoreCase().withIgnorePaths("id", "version", "associatedPicks", "segment");
diff --git a/common-service/pom.xml b/common-service/pom.xml
index b6e677fc..72f2fe06 100644
--- a/common-service/pom.xml
+++ b/common-service/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
gov.llnl.gnem.apps.coda.common
diff --git a/envelope-gui/pom.xml b/envelope-gui/pom.xml
index 093fda9b..fbb7cc97 100644
--- a/envelope-gui/pom.xml
+++ b/envelope-gui/pom.xml
@@ -7,7 +7,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
envelope-gui
diff --git a/envelope-service/envelope-application/pom.xml b/envelope-service/envelope-application/pom.xml
index f93a4aff..d749d480 100644
--- a/envelope-service/envelope-application/pom.xml
+++ b/envelope-service/envelope-application/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.envelope
envelope-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/envelope-service/envelope-model/pom.xml b/envelope-service/envelope-model/pom.xml
index d4904595..df2e4ab5 100644
--- a/envelope-service/envelope-model/pom.xml
+++ b/envelope-service/envelope-model/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.envelope
envelope-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/envelope-service/envelope-repository/pom.xml b/envelope-service/envelope-repository/pom.xml
index 4aad408d..f174c627 100644
--- a/envelope-service/envelope-repository/pom.xml
+++ b/envelope-service/envelope-repository/pom.xml
@@ -4,7 +4,7 @@
gov.llnl.gnem.apps.coda.envelope
envelope-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/envelope-service/envelope-service-api/pom.xml b/envelope-service/envelope-service-api/pom.xml
index 15cacf0a..d136eccb 100644
--- a/envelope-service/envelope-service-api/pom.xml
+++ b/envelope-service/envelope-service-api/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.envelope
envelope-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/envelope-service/envelope-service-impl/pom.xml b/envelope-service/envelope-service-impl/pom.xml
index cbc31199..98c904e8 100644
--- a/envelope-service/envelope-service-impl/pom.xml
+++ b/envelope-service/envelope-service-impl/pom.xml
@@ -6,7 +6,7 @@
gov.llnl.gnem.apps.coda.envelope
envelope-service
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/envelope-service/pom.xml b/envelope-service/pom.xml
index 00e61912..bfb4ffa5 100644
--- a/envelope-service/pom.xml
+++ b/envelope-service/pom.xml
@@ -5,7 +5,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
gov.llnl.gnem.apps.coda.envelope
diff --git a/envelope-standalone/pom.xml b/envelope-standalone/pom.xml
index ee8a5ae7..a8976067 100644
--- a/envelope-standalone/pom.xml
+++ b/envelope-standalone/pom.xml
@@ -6,7 +6,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
4.0.0
diff --git a/externals/pom.xml b/externals/pom.xml
index 5b885ade..983d8e4b 100644
--- a/externals/pom.xml
+++ b/externals/pom.xml
@@ -7,7 +7,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
externals
diff --git a/externals/src/main/java/llnl/gnem/core/gui/plotting/jmultiaxisplot/VPickLine.java b/externals/src/main/java/llnl/gnem/core/gui/plotting/jmultiaxisplot/VPickLine.java
index d25b9581..25a67dca 100755
--- a/externals/src/main/java/llnl/gnem/core/gui/plotting/jmultiaxisplot/VPickLine.java
+++ b/externals/src/main/java/llnl/gnem/core/gui/plotting/jmultiaxisplot/VPickLine.java
@@ -229,9 +229,10 @@ public void setWidth(int v) {
* @param v
* The new draggable value
*/
- public void setDraggable(boolean v) {
+ public VPickLine setDraggable(boolean v) {
canDragX = v;
window.setCanDragX(canDragX);
+ return this;
}
/**
diff --git a/mapping/pom.xml b/mapping/pom.xml
index 36f09f82..23d9ea98 100644
--- a/mapping/pom.xml
+++ b/mapping/pom.xml
@@ -7,7 +7,7 @@
gov.llnl.gnem.apps.coda.calibration
coda-calibration
- 1.0.9
+ 1.0.10
gov.llnl.gnem.apps.coda.common
diff --git a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/LeafletMap.java b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/LeafletMap.java
index 423a1aa8..2724ef2c 100644
--- a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/LeafletMap.java
+++ b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/LeafletMap.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -33,6 +33,7 @@
import gov.llnl.gnem.apps.coda.common.mapping.api.GeoShape;
import gov.llnl.gnem.apps.coda.common.mapping.api.Icon;
import gov.llnl.gnem.apps.coda.common.mapping.api.Icon.IconStyles;
+import gov.llnl.gnem.apps.coda.common.mapping.api.Icon.IconTypes;
import gov.llnl.gnem.apps.coda.common.mapping.api.Line;
import javafx.application.Platform;
import javafx.collections.FXCollections;
@@ -49,6 +50,9 @@
public class LeafletMap {
+ private static final LeafletIcon POLYGON_OUT_ICON = new LeafletIcon(null, null, IconTypes.POLYGON_OUT);
+ private static final LeafletIcon POLYGON_IN_ICON = new LeafletIcon(null, null, IconTypes.POLYGON_IN);
+
private static final Logger log = LoggerFactory.getLogger(LeafletMap.class);
private WebView webView;
@@ -59,11 +63,16 @@ public class LeafletMap {
private AtomicBoolean mapReady = new AtomicBoolean(false);
private Map> callbackMap = new HashMap<>();
private IconCallbackHandler iconCallbackHandler;
+ private PolygonChangeCallbackHandler polygonChangeCallbackHandler;
private List> eventCallbacks = new ArrayList<>();
private ContextMenu contextMenu;
private MenuItem reload = new MenuItem("Reload");
private MenuItem include = new MenuItem("Include");
private MenuItem exclude = new MenuItem("Exclude");
+ private MenuItem excludeOutPolygon = new MenuItem("Exclude outside");
+ private MenuItem includeOutPolygon = new MenuItem("Include outside");
+ private MenuItem excludeInPolygon = new MenuItem("Exclude inside");
+ private MenuItem includeInPolygon = new MenuItem("Include inside");
public class IconCallbackHandler {
private BiConsumer iconCallbackHandler;
@@ -77,6 +86,18 @@ public void accept(Boolean selected, String value) {
}
}
+ public class PolygonChangeCallbackHandler {
+ private Consumer polygonChangeCallbackHandler;
+
+ public PolygonChangeCallbackHandler(Consumer polygonChangeCallbackHandler) {
+ this.polygonChangeCallbackHandler = polygonChangeCallbackHandler;
+ }
+
+ public void accept(String value) {
+ polygonChangeCallbackHandler.accept(value);
+ }
+ }
+
public LeafletMap() {
iconCallbackHandler = new IconCallbackHandler((selected, id) -> {
BiConsumer callback = callbackMap.get(id);
@@ -85,6 +106,12 @@ public LeafletMap() {
}
});
+ polygonChangeCallbackHandler = new PolygonChangeCallbackHandler(geoJSON -> {
+ List> callbacks = new ArrayList<>(eventCallbacks);
+ MapCallbackEvent event = new MapCallbackEvent(null, MAP_CALLBACK_EVENT_TYPE.POLYGON_CHANGE, true, geoJSON);
+ callbacks.forEach(cb -> cb.accept(event));
+ });
+
Platform.runLater(() -> {
webView = new WebView();
webView.getEngine().setJavaScriptEnabled(true);
@@ -97,6 +124,7 @@ public LeafletMap() {
WebEngine engine = webView.getEngine();
contextMenu.getItems().clear();
Object activeIconId = engine.executeScript("getActiveIcon();");
+ Object activePolygonId = engine.executeScript("getActivePolygon();");
if (activeIconId instanceof String) {
icons.stream().filter(icon -> icon.getId().equalsIgnoreCase((String) activeIconId)).findFirst().ifPresent(icon -> {
include.setOnAction(e -> invokeActivationCallbacks(icon, true));
@@ -104,6 +132,13 @@ public LeafletMap() {
contextMenu.getItems().addAll(include, exclude);
contextMenu.show(webView, event.getScreenX(), event.getScreenY());
});
+ } else if (activePolygonId instanceof Boolean && ((boolean) activePolygonId == true)) {
+ excludeOutPolygon.setOnAction(e -> invokeActivationCallbacks(POLYGON_OUT_ICON, false));
+ includeOutPolygon.setOnAction(e -> invokeActivationCallbacks(POLYGON_OUT_ICON, true));
+ excludeInPolygon.setOnAction(e -> invokeActivationCallbacks(POLYGON_IN_ICON, false));
+ includeInPolygon.setOnAction(e -> invokeActivationCallbacks(POLYGON_IN_ICON, true));
+ contextMenu.getItems().addAll(excludeOutPolygon, includeOutPolygon, excludeInPolygon, includeInPolygon);
+ contextMenu.show(webView, event.getScreenX(), event.getScreenY());
} else {
contextMenu.getItems().addAll(reload);
contextMenu.show(webView, event.getScreenX(), event.getScreenY());
@@ -119,6 +154,7 @@ public LeafletMap() {
layers.forEach(this::addLayerToMap);
JSObject wind = (JSObject) webView.getEngine().executeScript("window");
wind.setMember("iconCallbackHandler", iconCallbackHandler);
+ wind.setMember("polygonChangeCallbackHandler", polygonChangeCallbackHandler);
return;
}
});
@@ -363,18 +399,8 @@ private String createJsIconRepresentation(Icon icon) {
}
private String addCallbacks(String id, String name) {
- return ".on('click', function() { iconCallbackHandler.accept(true, \""
- + id
- + "\"); }).bindPopup('"
- + name
- + "').on('popupclose', function() { iconCallbackHandler.accept(false, \""
- + id
- + "\"); }).on('mouseover', function() { if (\""
- + id
- + "\" !== mouseoverIconId) { mouseoverIconId = \""
- + id
- + "\"; }}).on('mouseout', function() { if (\""
- + id
+ return ".on('click', function() { iconCallbackHandler.accept(true, \"" + id + "\"); }).bindPopup('" + name + "').on('popupclose', function() { iconCallbackHandler.accept(false, \"" + id
+ + "\"); }).on('mouseover', function() { if (\"" + id + "\" !== mouseoverIconId) { mouseoverIconId = \"" + id + "\"; }}).on('mouseout', function() { if (\"" + id
+ "\" === mouseoverIconId) { mouseoverIconId = null; }})";
}
@@ -450,4 +476,12 @@ public void setShowOverlay(boolean showOverlay) {
public Boolean hasVisibleTileLayers() {
return (Boolean) webView.getEngine().executeScript("hasVisibleTiles();");
}
+
+ public String getPolygonGeoJSON() {
+ return (String) webView.getEngine().executeScript("getPolygonGeoJSON();");
+ }
+
+ public void setPolygonGeoJSON(String geoJSON) {
+ webView.getEngine().executeScript("setPolygonGeoJSON('" + geoJSON + "');");
+ }
}
diff --git a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/LeafletMapController.java b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/LeafletMapController.java
index 869ef1b3..234caf28 100644
--- a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/LeafletMapController.java
+++ b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/LeafletMapController.java
@@ -179,6 +179,18 @@ public void removeEventCallback(Consumer callback) {
mapImpl.removeEventCallback(callback);
}
+ @Override
+ public String getPolygonGeoJSON() {
+ return mapImpl.getPolygonGeoJSON();
+ }
+
+ @Override
+ public void setPolygonGeoJSON(String geoJSON) {
+ Platform.runLater(() -> {
+ mapImpl.setPolygonGeoJSON(geoJSON);
+ });
+ }
+
@Override
public int hashCode() {
final int prime = 31;
diff --git a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/MAP_CALLBACK_EVENT_TYPE.java b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/MAP_CALLBACK_EVENT_TYPE.java
index 6cce09b8..fff69e01 100644
--- a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/MAP_CALLBACK_EVENT_TYPE.java
+++ b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/MAP_CALLBACK_EVENT_TYPE.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2019, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
*
@@ -15,7 +15,7 @@
public enum MAP_CALLBACK_EVENT_TYPE {
- SELECTION("selection"), ACTIVATION("activation");
+ SELECTION("selection"), ACTIVATION("activation"), POLYGON_CHANGE("polygon_update");
private String type;
private MAP_CALLBACK_EVENT_TYPE(String type) {
diff --git a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/MapCallbackEvent.java b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/MapCallbackEvent.java
index bbbe825c..9c637807 100644
--- a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/MapCallbackEvent.java
+++ b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/MapCallbackEvent.java
@@ -19,12 +19,22 @@ public class MapCallbackEvent {
private final MAP_CALLBACK_EVENT_TYPE type;
private final boolean flag;
private final Icon icon;
+ private final String body;
public MapCallbackEvent(Icon icon, MAP_CALLBACK_EVENT_TYPE type, boolean flag) {
super();
this.icon = icon;
this.type = type;
this.flag = flag;
+ this.body = null;
+ }
+
+ public MapCallbackEvent(Icon icon, MAP_CALLBACK_EVENT_TYPE type, boolean flag, String body) {
+ super();
+ this.icon = icon;
+ this.type = type;
+ this.flag = flag;
+ this.body = body;
}
public Icon getIcon() {
@@ -38,4 +48,8 @@ public boolean getFlag() {
public MAP_CALLBACK_EVENT_TYPE getType() {
return type;
}
+
+ public String getBody() {
+ return body;
+ }
}
diff --git a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/api/GeoMap.java b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/api/GeoMap.java
index 38ff6109..aaee49fa 100644
--- a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/api/GeoMap.java
+++ b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/api/GeoMap.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -47,4 +47,8 @@ public interface GeoMap {
public void removeEventCallback(Consumer callback);
public void show();
+
+ public String getPolygonGeoJSON();
+
+ public void setPolygonGeoJSON(String geoJSON);
}
diff --git a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/api/Icon.java b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/api/Icon.java
index 4abd060a..dd0db512 100644
--- a/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/api/Icon.java
+++ b/mapping/src/main/java/gov/llnl/gnem/apps/coda/common/mapping/api/Icon.java
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2018, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
+* Copyright (c) 2020, Lawrence Livermore National Security, LLC. Produced at the Lawrence Livermore National Laboratory
* CODE-743439.
* All rights reserved.
* This file is part of CCT. For details, see https://github.com/LLNL/coda-calibration-tool.
@@ -18,10 +18,10 @@
public interface Icon {
- public static final String FOCUS_TAG = "!!";
+ public static final String FOCUS_TAG = "!!";
public enum IconTypes {
- DEFAULT, CIRCLE, TRIANGLE_UP
+ DEFAULT, CIRCLE, TRIANGLE_UP, POLYGON_OUT, POLYGON_IN
}
public enum IconStyles {
diff --git a/mapping/src/main/resources/leaflet/images/Circle.svg b/mapping/src/main/resources/leaflet/images/Circle.svg
new file mode 100644
index 00000000..5263da9f
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Circle.svg
@@ -0,0 +1,15 @@
+
diff --git a/mapping/src/main/resources/leaflet/images/CircleMarker.svg b/mapping/src/main/resources/leaflet/images/CircleMarker.svg
new file mode 100644
index 00000000..5b71e7a8
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/CircleMarker.svg
@@ -0,0 +1,7 @@
+
+
+
\ No newline at end of file
diff --git a/mapping/src/main/resources/leaflet/images/Edit_Vertex.png b/mapping/src/main/resources/leaflet/images/Edit_Vertex.png
new file mode 100644
index 0000000000000000000000000000000000000000..9c639eedf8f950524d5ec6aee5144ca3c9964bd1
GIT binary patch
literal 2018
zcmV<82Oao{P)EX>4Tx04R}tkv&MmKpe$i(@Iq;9qgdukfAzR5ET(zvs^dzd7t}p^eB0g0X~st?f%Ws^E4huXpVr0^D#1Ue#*v4`jvy!0_PY_2HRik_%
z>$1Xmi?dp;vgSSc3qyHrd5P;Z2a&)67LkGo8C7hc3=1(@HBwBZX+Q4aA8`CBa>?Y{
z03*jdDo`Oge(*o|-K|*|A9IsJaiHVHwm*h|;4aXp+4lFbZ8uH;|1)rYT&=zG#7LvkcPO`%W#-p}ZpazO7b(7o#R*4)SG1CXJvk~hG?
zAuwE|>@|;fceeNT@0n(QKY`(Lty!nefB*mh24YJ`L;(K){{a7>y{D4^000SaNLh0L
z0E%e<0E%e=v1PL|00007bV*G`2jmF^5E}$>4yxe*00rJjL_t(|+U;9?Y!p=x|IORw
zT2mlb4Q(JuO#C>JVl=t-Ep0dxMNy+gQ6vpQqCpf4NDUQ>LZ~2MB7`6x#sZ>5B_L`V
z6a)StC8hh?BO23)h#y2C2BWl!m0sJu@sD1Urn%j=$L{s6*ZJp?eKV7p-_DzvH}95^
zCR9{ZbUP7k2T)?e5+$OY%v_ZhI5bNse>woO^)&tDE6~Htb)ePWWW?tUV(D3Kg*yt4iB&A#p
zUV#TTY)o-RYXKZhJ4KtOBsgRYZvn5K(!3efW5fBQ6Mnoc!KjLKj
zbCzY@5e|nh^?Vo%2CvmL?OOoX_r{T#Cp9!Q{E&XHBCEWCtz9D(YQtlF)keeu*(ZhZ_^s=R@+SgevjL-G2de+pzHc{
z8<`7f2Y}D#`##p*_IBp=U@$l)PRYEEnK#B!b*ZJL
zlcs4W4Z~Q*%wNV5>n`7YSg0br6+>P*Tcsd)6k?`Gg|CFpL~#UIn1sq2+Cf*Aw(XA1S5g#E!bDSp}q&Gnx4mfR}8X
zzXD*TrfFjVtd50re`!K67|cm_8SGaC6c!fVD1>+mzyl6!p95H;l=`IyU^mBR0y6;Q
z_T%t#%;)nxSX*2BUrGQ_TwI)OS=Mp@F9XQ7VfzihQl-?Vc6tJVfbRGEC-%ttFFH(n
zj%u1#dg8>1wm}8JFpRsIc^iORZCE-1Y}a-D)w;U6%LB|K`ch-3xz^Y^ffqj4S+x(py%f1KF`c+0F1KX
zzXYICDOH_>Z2d?i64@6B1ZI2L7>QU&PWAi!-!SuL8|N9oUSBusFvPWMg%1H(Xqx7Eqz*kTrEFD7E%CAwJOg05QtDx)R4O^&O^Xe~*yIHO
zSBR*pwY7D!QtAj&n3%a-O8J_bTc9QyjlR&>*mxG{Lo20}?MkV&gFO#Oi2Bh9_LnM^
zQX7(X8cac2Zx}{JCIbLwenU#RC}RPLZR4#{$_1GUKsN|Gq?Au)DgfQS>@f_ZEK>mh
z0F9a7lTyyeQ~-dkS>=8y2d_YP$EmHvix@MSrG8q5>=<`6Qr>SFS0jzhd
zi$qZG#=Izyu;XYMSP+ZqEbKrsgyAGj7fU(y#R+nqN>*kTsM6*n+O>HoHU6n2{q#
z&K!~e5YaBB)KVha(Z@+};ZOu%PhMW$0sx$smvOf+
z`;d8dr~q)VrKM#~I2^Wmg?Tjqr%Td#B_$=J(j9=$va+(u;@ttpZlgYNkR8?8*;$ru
z05tbVcwbnSHQVVHxUXbLM9-xa07SGAz*hiv3n3m0hr{ho{HAFh2hikD4em4yLndO&
zptQoVZ-nk0pxE00wmN`N06-1pPH-=Pe{I&j)->&4LeZE`?XO`N+j}%W9RNNCuvsb9
zkf_eIIt?=OD*)O7Gz%eidhrd>Fb&f%4O2$Z|3f1tv}+5QivR!s07*qoM6N<$f
+
+
+
+
+
+
+
+
+
+
diff --git a/mapping/src/main/resources/leaflet/images/Eraser.png b/mapping/src/main/resources/leaflet/images/Eraser.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a6529d2bb7ad23af09515b17ce2ee1ef50393a6
GIT binary patch
literal 2193
zcmV;C2yXX@P)EX>4Tx04R}tkv&MmKpe$i(@Iq;9qgdukfAzR5ET(zvs^dzd7t}p^eB0g0X~st?f%Ws^E4huXpVr0^D#1Ue#*v4`jvy!0_PY_2HRik_%
z>$1Xmi?dp;vgSSc3qyHrd5P;Z2a&)67LkGo8C7hc3=1(@HBwBZX+Q4aA8`CBa>?Y{
z03*jdDo`Oge(*o|-K|*|A9IsJaiHVHwm*h|;4aXp+4lFbZ8uH;|1)rYT&=zG#7LvkcPO`%W#-p}ZpazO7b(7o#R*4)SG1CXJvk~hG?
zAuwE|>@|;fceeNT@0n(QKY`(Lty!nefB*mh24YJ`L;(K){{a7>y{D4^000SaNLh0L
z0E%e<0E%e=v1PL|00007bV*G`2jmF^5E?i~dgmtq00xaoL_t(|+U;9wY*a-Q{?6V)
zgVqRWsNk#wNF++5(e8HcQdt!rXyv6SiV>qRzTYwUNYtn?YK)ImeyTCXKr{r!f+d0q
z)Jo@UF9v80!Kkrz@0x&3t5)mMy&ZqF8Zh^6cenR$x7hFRnVp&Q?U{4tJF^RnV;tl7
zKZ8nbLsH6R0B!~_4?rJ)CL&s^l=|+tCZMXSs=T72;ytbPbuQ*UB6>h6^_Ji38l@76
zvu4eD2f!*1`vd?>g%DG#tE;yiJa|waR}o;E=1W@Z$8sFL(Q%yBmSy!F7X(NtZv&8T
zXty|yv&^!r!(*BN(=@NpT5kqWmiNYqz9*u(mX?-p$0Px!X;x{in*p3Wf@!+6*2@!#
zM024Nghs>pXf!%QYuz|P=Kg=VJ*ngf
zFirC*0CyE(sYRJg=F3b8?=A`f
z@p$|M$8oj|Y5G#>dt5GrXtQnmK%iA15{Ve;bb392C`u161YQOW!+0IQGL$CfMx)U=
zfe|33dqbjm=7D|8+~F$$Qp(v{>xQA4
zTguQxw8qyY7>Put0%!y<&BfdcpreFB|4F6PcHanyL?ROn!`J{|u8Y|La8oE0swSdc
zCE)zqN~st8RD)y~##;aude|Ri=8s!iTDp3BdlvzCcNG2qw7a|eE?>2Pl=4LY_j;IL
zX6Ap{K6L1iW83zoa5&sE)C(x4B5ZdYr>?E7tloUH#If=IgCg;hlm;g%nZ=^--&2}Qfi-X4Uu8m
z*gp_aOeu9JN2Pcw5q$_?K>*J816ab$pXMqRheb3Rok2u9Jjz{HC=^<#l=>;x9on}2
z=aeZ^)=!)`aVCIseJ0?3W_~{(t(+CZw6XspqAQhBd-L7pKgm%D(Kl30{78<^GxN*&
zHVd-p`U(C0{U5=-jjaLP!pw~$*|BZgUxmZrZvZUD;45&Uwf=o(zAxX;Wvv27jvT26
zu*k!_hMCv<5wl9EjYKpbz)uBE(bU`9d&|(5;tv5*$|tqfcYB!MWM*HLpHgZc5t#s5
z^Ze)m0L$Ck+tY=t8}e}edH~OPgj!=yPtQF;)Gnpe&xT>diD+GpVSkv2mNIj9!3`Xj
za(6y}EgrRgkK;It+uGXx3aWs2c6Mfx$>c{u2m%n#k{tgaqRW(0?IT&wEduJ{-ox)8
zq9vAP^%g_AmY0`54`9EC-O*aFQc77PU8wB8^0_Bd;|ClZPM#d2Os`80q#J*>WMDq?;OXuY&dD_OBu9n+Y&;|
z08s6bG_Mgt9I(0=P8Dg$>dHU#E$^3@)&oX<2bSD
z)2BD2QmJ%-&Krhdd;s8553zMCGk+3f-pMM4nE71*R|4qq7;>p$7|pR*?2LlgAACn#
z?qPnEnb#p;Y(I;8jSScb}qLlhNkEHhqfLF4JtviZQc5`ZqCK8Enh$seN
zkH?T1TI*e=XqTGd#qfSg
z+e$=%>J6>+Ys{?jCg7;VRS)lXfw6#<%)BAzBXBe<%W|0cJ|cPuzyQWL3Vs_@O4Sq5
zN(}z5=l@5*5D6OrEF_}CW0ioikxszON=jJ^;8`Ln8w*ZrtvfM}ag1Xe;{g5!T!~p|
TFCg=@00000NkvXXu0mjf+kFdc
literal 0
HcmV?d00001
diff --git a/mapping/src/main/resources/leaflet/images/Eraser.svg b/mapping/src/main/resources/leaflet/images/Eraser.svg
new file mode 100644
index 00000000..1c2c2779
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Eraser.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/mapping/src/main/resources/leaflet/images/Line.svg b/mapping/src/main/resources/leaflet/images/Line.svg
new file mode 100644
index 00000000..783fc687
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Line.svg
@@ -0,0 +1,11 @@
+
diff --git a/mapping/src/main/resources/leaflet/images/Magnet.svg b/mapping/src/main/resources/leaflet/images/Magnet.svg
new file mode 100644
index 00000000..0eb37d59
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Magnet.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/mapping/src/main/resources/leaflet/images/Marker.svg b/mapping/src/main/resources/leaflet/images/Marker.svg
new file mode 100644
index 00000000..bd95fbd0
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Marker.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/mapping/src/main/resources/leaflet/images/Move.png b/mapping/src/main/resources/leaflet/images/Move.png
new file mode 100644
index 0000000000000000000000000000000000000000..977236ffbe5f1f12ad8682f3dcde1c22c791e9a3
GIT binary patch
literal 1456
zcmV;h1yA~kP)EX>4Tx04R}tkv&MmKpe$i(@Iq;9qgdukfAzR5ET(zvs^dzd7t}p^eB0g0X~st?f%Ws^E4huXpVr0^D#1Ue#*v4`jvy!0_PY_2HRik_%
z>$1Xmi?dp;vgSSc3qyHrd5P;Z2a&)67LkGo8C7hc3=1(@HBwBZX+Q4aA8`CBa>?Y{
z03*jdDo`Oge(*o|-K|*|A9IsJaiHVHwm*h|;4aXp+4lFbZ8uH;|1)rYT&=zG#7LvkcPO`%W#-p}ZpazO7b(7o#R*4)SG1CXJvk~hG?
zAuwE|>@|;fceeNT@0n(QKY`(Lty!nefB*mh24YJ`L;(K){{a7>y{D4^000SaNLh0L
z0E%e<0E%e=v1PL|00007bV*G`2jmF^5E~YPx7(=z00XQ^L_t(|+U=UpYZE~f$G7&(%@a_!5>BRpjQzO-n8hYe}HHUf{0o$UMeLsTJWZ%
zl!D;mK{2JbYPaJhmKqx~o6PKwr0hpv;57ga
zU`$F`>KXxv=r8~Y;9%{eD(BoQm&+?1F8~qs0w@DGQukE_KtW1bjWQn|<&Wj_c?ZDb
zJ&Ff_9Duo8E|=+80UXDf0WkKTOGf+p`tC)VQ-nkR0)X2ZmkztG`_1?L_Z`E4UBu67
z-m(>yGq4DXuP454MB)t0a`BCbuN&5#!5Rdc5MMW}JA*X=G>ESoR-M7IH1u_euN&5!
zfmtX%Eb(>2iZd|7#kWfQ*qnhGEWTah$KnjJbc3Gf%_*fO|4M|hc_BnG>RdRwJb0VK
zzCZ2)+RcHtF^mTQEG6J2zVke9C{h7D&pWP^DgziwfB*wZsU;#BjYI$%=v1oOz
zL_dH9BAO0+qxKp*pU*p)Oy-VK>PA9&<^Z_wdEU`%HhXz-aq*Y25kN$}j^jK_aPd2#
zl$zSy+)NB{*o~C@hhuT*FP?S=Z
z7!geYcmUu)mo|~YHVEKRm}Re&GW52Z$t^J=QXwuc)!uw{&vk&5
zaw7a3U0M~>NGog9`Ddj9<>?DBi
zDTm!DDdkK{-JlTSEn}qsEWP`M&?zb=|K3
zCJaCNij?w+>3pr66ZC!mgX_A7030*)$cIwOTQ+jF<^n+wOapjjqOnKDJ5xVx>~qN}T`(oWVHpV_68b=nPhf9~lG6*n0sDXRu2A
z*ac|f4AzOCh;FcfGekoC#I(b8&JY>#V})P?XZQhNAu8hU6~6%$D&X?M;z6$f0000<
KMNUMnLSTZ&P@o_H
literal 0
HcmV?d00001
diff --git a/mapping/src/main/resources/leaflet/images/Move.svg b/mapping/src/main/resources/leaflet/images/Move.svg
new file mode 100644
index 00000000..a62cc593
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Move.svg
@@ -0,0 +1,11 @@
+
diff --git a/mapping/src/main/resources/leaflet/images/Polygon.png b/mapping/src/main/resources/leaflet/images/Polygon.png
new file mode 100644
index 0000000000000000000000000000000000000000..820ce834ea6948cabce7335e90108258daad8eb6
GIT binary patch
literal 1847
zcmV-72gvw|P)EX>4Tx04R}tkv&MmKpe$i(@Iq;9qgdukfAzR5ET(zvs^dzd7t}p^eB0g0X~st?f%Ws^E4huXpVr0^D#1Ue#*v4`jvy!0_PY_2HRik_%
z>$1Xmi?dp;vgSSc3qyHrd5P;Z2a&)67LkGo8C7hc3=1(@HBwBZX+Q4aA8`CBa>?Y{
z03*jdDo`Oge(*o|-K|*|A9IsJaiHVHwm*h|;4aXp+4lFbZ8uH;|1)rYT&=zG#7LvkcPO`%W#-p}ZpazO7b(7o#R*4)SG1CXJvk~hG?
zAuwE|>@|;fceeNT@0n(QKY`(Lty!nefB*mh24YJ`L;(K){{a7>y{D4^000SaNLh0L
z0E%e<0E%e=v1PL|00007bV*G`2jmF^5E~2OvA1vl00lEiL_t(|+U;9SY#UV&{${gL
z!hy=BLK~=k1S=G(ipy?g7{NBl`G5(h*%G=Kp0LLE@ZffkSoH$oS0xBuUeY
zi;I7{%`p(wovW&9hM9i^@Faj?hiC2su%DUVNhXs6#bWXDPT2vZs%jR%Yi*7@Cxmzt
z07rTUsH&O)@ScyMPb3lvE|p4`BfA6aGk+DppwB5xBHE|x`nAmuq$m+!2RtY6D@62?
zEX%uOS>8oNF90YwJSQ{rN0HnC>2!KvTgt{9Eh2*172gw+|A4<9i}qM
z?bQ>i|_%PXjpWlm_j9cgbGigEsht!?S0E5O3YyC6TIuiGF8hr>~L#e%i7tniWDb
zcLc@;OBfz^96$
z9LeYNR-|5sTY%pH@IHWVU54KxqVvprN(k{seuD2i0sRKwR|3KSzHbDC1$cOU6;TAeP13=ckuKK1Q;5AJfWoEaQ_kRG+GxN!%rKRO|2_RKfPXIU$
z|M!PI13xh_A+4^iW&nJQ)`F=TfG-q9$>egmx)%cc>hJ;szqYoPW#(7g8An7}(=-n^
zw#&Ea1Ut~-1+wj9vDg%VcYO@qCrOgkR41ruT8f#kqO)uBqe6)9dU)oqpfjD|<6Cct
zsbTfc066S0aD|8_Hw8(SWsNiQ41iQfvROO+-64>mt*Nd{I=sNax9Oi@7{-H}De`t9
z)I}X$pytEBSUeuz>r@GLO@|kx`SFjLyQ33y)8U21-25XVb}EJcc9~=xz?@?pEz1X7
z1WA(sO5HAR0esaB|CqVt76exTG-~b&0LJVywY5y%U9Z=F!*(g!Ez7bV@OnS*)l#XH
z9E-))0o>oAf9r-}D4Rjha~gz49Uc*Vuj~5Tz1Y&Ks{R1rNGJZGnNCoWr0IIS{<=e<
z;Z=uMW9C!6I@8SjB@w;RiGKj5T}$C&vG{K?nH&J{tWO`Ogb){cML?-k`X`Y{$N-+{
zz`xn14G~?}GXT!{nEb4wD4+K_vMY*`A)>60dLb)>_-tDmbzyookw`Frr_lP3RVERg
zuq^At`T6;JuL&p=3Oq70@{1%%7J#Qcr1F}*^2gBdkFk~w5mi+mv3mlC9I}G}V2+4p
z8s(=!nf>zi34rGvs@Qb^IRMi_h`)Swgc?%Ns2x>_h)U&hdD%V-^{TurhH)({{@t@M+y7!7AI&6IR(Jpa002ovPDHLkV1kF*S5E){
literal 0
HcmV?d00001
diff --git a/mapping/src/main/resources/leaflet/images/Polygon.svg b/mapping/src/main/resources/leaflet/images/Polygon.svg
new file mode 100644
index 00000000..1b169a3f
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Polygon.svg
@@ -0,0 +1,11 @@
+
diff --git a/mapping/src/main/resources/leaflet/images/Rectangle.png b/mapping/src/main/resources/leaflet/images/Rectangle.png
new file mode 100644
index 0000000000000000000000000000000000000000..957337228fd66db72891147e034a1c116ea09ced
GIT binary patch
literal 2057
zcmah~`8yPP7ypiBXrwWPTxH8-dn_ZaZk8F%Vkv8xiXr9IXe^l-T-3PcwcROY7?LH;
zC?YW>dzQEuZy|+C3E9drS&A{^`w;c%RSnIp=vk=ZABi=X1_;ZhE*mD#FxZ002d2
zC;XY+Z2yz;(A`)@p^XCoNv7a%9?m$NHkBSuri5Mrz#tc&lkeWMXN&>CReA3Uk8r
zUFpYlab?(XH?U(tEw0(RYmE{)U#}=8u$e1XRN7eojNJrXZth0^Q5+qKaV_)!<9&1a
zbo*tKcg+jyL!({u(&>eK&hgeZ9h7g;w_n-O(Y50B++=HHX_3h$D)%w1og0jC}D
zVCN@z%_W(;${wndcLV^pC_f3Qyi#>+SCor%b|uKo?2%DAgg89lw(Bue)){}&D`sSo
zL<&_Vs%>xQQkeLV^8t@rzdgG4hTwGSnBSehljImi>N**x@drL55lJ$g3MQ5{dQxaf
zFupLI1zS_}_qdo-^$~Ax%16H-jXoT!$&i}w*+NI2s;#nE?5Q5eM(s@dzGdu0zh%r~
zf?6P)nCip?-@)IM8@Sl-t*20FagVJc*pe^-UDk&}y&(srk97$8JyDeq;OiAwe_
z`C`b2!~2J6L}Hy-EdE5(H|zdU2Wpd=L`g~k`S~&*|8*e>@&N()RHdt{YoMBn>2kKW
zEU2vzG
zpxg~dk2E2x(b1Ue0UzBY|9S;&u#eQL0|1GnBm-6`K#gK;q~!5+q^$VK35xu
zxT3jQ^kySNa1T=CHw-6bi)LID0`xLH^YZeHfM&j4%bNsQg~9KJoZytnbmeNk~=oi+V#k
zPHIl$)pyTy_AsvU_pq4He4cpmV}~Fw`SH>diq9y5-0`<3_O^VpmUlptG9}D)FicG#
zrbR_mUf3cHR6~K8L&q>hO~5`tmVtZDL#ejdP5t{S=gSMrg7ul1h--G_JhJe4ZxX>yV*XzM_J0D8!2~UR7~{&GHrp#MFCPhG
z=<6UxQS|n9C6txjB{B>x%LyQDVL(aFhKK3BM%7!O>sGB6lN(fO$K-g$0rE*&Z-x0$mcLWvQcTuR=ju}@#3
z)U~^R=p#6C%-%2b*!aA^uy6EXV>Twepio|>hJH=Bp`H}dh-A*1Pm-b2>p
zCE0YE-*9WsaFidrSezU8su|i@f?C}K3yS;G+*hm?{Dv>b#Z+lr{!V=Q_rlrfb31bC
zRPoZ-UCq~ttlt|B$pIa_tochUjzzk_aDCzxOel~)#Too2VzSU}-l+zXoLGtm1g|_Y
zy7K(LG9eKaDs3e6opNcaKzRS5fiNzKGF1M;bHzO3wYy9=7=6$v#VlWSvtxx?HGZgF
zJY8D%u#=LliETc6)VQTExTY*EmDjlMH`t}dd;Ldva5k&u*xu>I-%_giLVxL)2y4m2
zk3DXs(n#lp%CH-$j)fTxcZAnD8!=hA@Gg;?#p*1+I?7rCT&TBP4X)qnoWjgU`Z(aZ
z+DvII>jNVpjqQ07&*dd9uN8$rx`fe3u+v>$#KknyM4AptDZ~VdRTn
l*XWf#72`Q(5>8IvcZ|Bitj9GQo1d=)I1}9PeC(x!{{bQ1%q;)_
literal 0
HcmV?d00001
diff --git a/mapping/src/main/resources/leaflet/images/Rectangle.svg b/mapping/src/main/resources/leaflet/images/Rectangle.svg
new file mode 100644
index 00000000..930702f7
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Rectangle.svg
@@ -0,0 +1,11 @@
+
diff --git a/mapping/src/main/resources/leaflet/images/Scissors.svg b/mapping/src/main/resources/leaflet/images/Scissors.svg
new file mode 100644
index 00000000..a6eb272c
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/images/Scissors.svg
@@ -0,0 +1,17 @@
+
+
\ No newline at end of file
diff --git a/mapping/src/main/resources/leaflet/leaflet-geoman.css b/mapping/src/main/resources/leaflet/leaflet-geoman.css
new file mode 100644
index 00000000..3d4a8daa
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/leaflet-geoman.css
@@ -0,0 +1,213 @@
+.marker-icon,
+.marker-icon:focus {
+ background-color: #ffffff;
+ border: 1px solid #3388ff;
+ border-radius: 50%;
+ margin: -8px 0 0 -8px !important;
+ width: 14px !important;
+ height: 14px !important;
+ outline: 0;
+ transition: opacity ease 0.3s;
+}
+
+.marker-icon-middle,
+.marker-icon-middle:focus {
+ opacity: 0.7;
+ margin: -6px 0 0 -6px !important;
+ width: 10px !important;
+ height: 10px !important;
+}
+
+.leaflet-pm-draggable {
+ cursor: move !important;
+}
+
+.cursor-marker {
+ cursor: crosshair;
+ pointer-events: none;
+ display: none;
+}
+
+.cursor-marker.visible {
+ display: block !important;
+}
+
+.leaflet-pm-invalid {
+ stroke: red;
+ transition: fill ease 0s, stroke ease 0s;
+}
+
+.rect-style-marker,
+.rect-start-marker {
+ opacity: 0;
+}
+
+.rect-style-marker.visible,
+.rect-start-marker.visible {
+ opacity: 1 !important;
+}
+
+.hidden {
+ display: none;
+}
+
+.vertexmarker-disabled {
+ opacity: 0.7;
+}
+
+.leaflet-pm-toolbar {}
+
+.leaflet-pm-toolbar .leaflet-buttons-control-button {
+ padding: 5px;
+ box-sizing: border-box;
+ position: relative;
+ z-index: 3;
+}
+
+.leaflet-pm-toolbar .leaflet-pm-actions-container a:first-child:not(.pos-right) {
+ border-radius: 0 !important;
+}
+
+.leaflet-pm-toolbar .leaflet-pm-actions-container a:last-child.pos-right {
+ border-radius: 0 !important;
+}
+
+.leaflet-pm-toolbar .button-container .leaflet-buttons-control-button {
+ border-radius: 0 !important;
+}
+
+.leaflet-pm-toolbar .button-container:last-child .leaflet-buttons-control-button {
+ border-radius: 0 0 2px 2px !important;
+}
+
+.leaflet-pm-toolbar .button-container:first-child .leaflet-buttons-control-button {
+ border-radius: 2px 2px 0 0 !important;
+}
+
+.leaflet-pm-toolbar .control-fa-icon {
+ font-size: 19px;
+ line-height: 24px;
+}
+
+.leaflet-pm-toolbar .control-icon {
+ width: 100%;
+ height: 100%;
+ box-sizing: border-box;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center center;
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-marker {
+ background-image: url(images/Marker.svg);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-polygon {
+ background-image: url(images/Polygon.png);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-polyline {
+ background-image: url(images/Line.svg);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-circle {
+ background-image: url(images/Circle.svg);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-circle-marker {
+ background-image: url(images/CircleMarker.svg);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-rectangle {
+ background-image: url(images/Rectangle.png);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-delete {
+ background-image: url(images/Eraser.png);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-edit {
+ background-image: url(images/Edit_Vertex.png);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-drag {
+ background-image: url(images/Move.png);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-cut {
+ background-image: url(images/Scissors.svg);
+}
+
+.leaflet-pm-toolbar .leaflet-pm-icon-snapping {
+ background-image: url(images/Magnet.svg);
+}
+
+.leaflet-buttons-control-button:hover {
+ cursor: pointer;
+ background-color: #f4f4f4;
+}
+
+.active .leaflet-buttons-control-button {
+ box-shadow: inset 0 -1px 5px 2px rgba(81, 77, 77, 0.31);
+}
+
+.leaflet-buttons-control-text-hide {
+ display: none;
+}
+
+.button-container {
+ position: relative;
+}
+
+.button-container .leaflet-pm-actions-container {
+ z-index: 2;
+ position: absolute;
+ top: 0;
+ left: 100%;
+ display: none;
+ white-space: nowrap;
+}
+
+.leaflet-right .leaflet-pm-toolbar .button-container .leaflet-pm-actions-container {
+ right: 100%;
+ left: auto;
+}
+
+.button-container.active .leaflet-pm-actions-container {
+ display: block;
+}
+
+.button-container .leaflet-pm-actions-container:not(.pos-right) .leaflet-pm-action:last-child {
+ border-radius: 0px 3px 3px 0px !important;
+ border-right: 0px;
+}
+
+.button-container .leaflet-pm-actions-container.pos-right .leaflet-pm-action:first-child {
+ border-radius: 3px 0px 0px 3px !important;
+}
+
+.button-container .leaflet-pm-actions-container.pos-right .leaflet-pm-action:last-child {
+ border-right: 0px;
+}
+
+.button-container .leaflet-pm-actions-container .leaflet-pm-action {
+ padding: 0px 10px;
+ background-color: #666;
+ color: #fff;
+ display: inline-block;
+ width: auto;
+ border-right: 1px solid #eee;
+ user-select: none;
+}
+
+.button-container .leaflet-pm-actions-container .leaflet-pm-action:hover {
+ cursor: pointer;
+ background-color: #777;
+}
+
+
+/* That the active control is always over the other controls */
+
+.leaflet-pm-toolbar.activeChild {
+ z-index: 801;
+}
diff --git a/mapping/src/main/resources/leaflet/leaflet-geoman.min.js b/mapping/src/main/resources/leaflet/leaflet-geoman.min.js
new file mode 100644
index 00000000..261ad4a5
--- /dev/null
+++ b/mapping/src/main/resources/leaflet/leaflet-geoman.min.js
@@ -0,0 +1 @@
+!function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)r.d(n,i,function(e){return t[e]}.bind(null,i));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=60)}([function(t,e,r){"use strict";function n(t,e,r){void 0===r&&(r={});var n={type:"Feature"};return 0!==r.id&&!r.id||(n.id=r.id),r.bbox&&(n.bbox=r.bbox),n.properties=e||{},n.geometry=t,n}function i(t,e,r){return void 0===r&&(r={}),n({type:"Point",coordinates:t},e,r)}function a(t,e,r){void 0===r&&(r={});for(var i=0,a=t;i line1 must only contain 2 coordinates");if(2!==n.length)throw new Error(" line2 must only contain 2 coordinates");var o=r[0][0],s=r[0][1],l=r[1][0],h=r[1][1],c=n[0][0],u=n[0][1],p=n[1][0],f=n[1][1],d=(f-u)*(l-o)-(p-c)*(h-s);if(0==d)return null;var g=((p-c)*(s-u)-(f-u)*(o-c))/d,_=((l-o)*(s-u)-(h-s)*(o-c))/d;if(0<=g&&g<=1&&0<=_&&_<=1){var m=o+g*(l-o),y=s+g*(h-s);return i.point([m,y])}return null}e.default=function(t,e){var r={},n=[];if("LineString"===t.type&&(t=i.feature(t)),"LineString"===e.type&&(e=i.feature(e)),"Feature"===t.type&&"Feature"===e.type&&null!==t.geometry&&null!==e.geometry&&"LineString"===t.geometry.type&&"LineString"===e.geometry.type&&2===t.geometry.coordinates.length&&2===e.geometry.coordinates.length){var c=h(t,e);return c&&n.push(c),i.featureCollection(n)}var u=l.default();return u.load(o.default(e)),s.featureEach(o.default(t),(function(t){s.featureEach(u.search(t),(function(e){var i=h(t,e);if(i){var o=a.getCoords(i).join(",");r[o]||(r[o]=!0,n.push(i))}}))})),i.featureCollection(n)}},function(t,e,r){var n=r(18),i=r(76),a=r(77),o=n?n.toStringTag:void 0;t.exports=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":o&&o in Object(t)?i(t):a(t)}},function(t,e,r){var n=r(64),i=r(65),a=r(66),o=r(67),s=r(68);function l(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e>1],s=n-1,l=i+1;;){for(;a(e[++s],o)<0;);for(;0n[0]?1:r[0]n[1]?1:-1:function(t,e,r,n){return t.left===e.left?0===l(r,t.otherEvent.point,e.otherEvent.point)?!t.isSubject&&e.isSubject?1:-1:t.isBelow(e.otherEvent.point)?-1:1:t.left?1:-1}(t,e,r)}function c(t,e,r){var n=new o(e,!1,t,t.isSubject),i=new o(e,!0,t.otherEvent,t.isSubject);return s(t.point,t.otherEvent.point)&&console.warn("what is that, a collapsed segment?",t),n.contourId=i.contourId=t.contourId,0e.contourId?1:-1):1===h(t,e)?1:-1}function g(t,e,r,n){var i=t+1,a=e.length;if(a-1>1)-1;0<=r;r--)this._down(r)}function v(t,e){return t>1,a=e[i];if(0<=r(n,a))break;e[t]=a,t=i}e[t]=n},_down:function(t){for(var e=this.data,r=this.compare,n=this.length>>1,i=e[t];tn[2]||n[0]>r[2]||r[1]>n[3]||n[1]>r[3])&&(0===i?a=w:2===i?a=t:1!==i&&3!==i||(a=t.concat(e))),a}(t,e,o,s,n))?a===w?null:a:function(t,e){var r,n,i,a=function(t){var e,r,n,i,a=[];for(r=0,n=t.length;rg||2===s&&_.point[0]>a[2])break;if(_.left){h=l=u.insert(_),l=l!==(c=u.minNode())?u.prev(l):null,h=u.next(h);var m=l?l.key:null;if(i(_,m,s),h&&2===f(_,h.key,t)&&(i(_,m,s),i(_,h.key,s)),l&&2===f(l.key,_,t)){var y=l;i(m,(y=y!==c?u.prev(y):null)?y.key:null,s),i(_,m,s)}}else _=_.otherEvent,h=l=u.find(_),l&&h&&(l=l!==c?u.prev(l):null,h=u.next(h),u.remove(_),h&&l&&f(l.key,h.key,t))}return p}(l,0,0,o,s,n),n)}var x={UNION:1,DIFFERENCE:2,INTERSECTION:0,XOR:3};t.union=function(t,e){return C(t,e,1)},t.diff=function(t,e){return C(t,e,2)},t.xor=function(t,e){return C(t,e,3)},t.intersection=function(t,e){return C(t,e,0)},t.operations=x,Object.defineProperty(t,"__esModule",{value:!0})}(e)},function(t,e,r){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=r(3),i=6378137;function a(t){var e=0;if(t&&0>>0,n=arguments[1],i=0;i>>0,n=arguments[1],i=0;i>>0;if(0==n)return!1;for(var i,a,o=0|e,s=Math.max(0<=o?o:n-Math.abs(o),0);s=t.minX&&e.maxY>=t.minY}function g(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function _(t,e,r,i,a){for(var o,s=[e,r];s.length;)(r=s.pop())-(e=s.pop())<=i||(o=e+Math.ceil((r-e)/i/2)*i,n(t,o,e,r,a),s.push(e,o,o,r))}i.prototype={all:function(){return this._all(this.data,[])},search:function(t){var e=this.data,r=[],n=this.toBBox;if(!d(t,e))return r;for(var i,a,o,s,l=[];e;){for(i=0,a=e.children.length;ithis._maxEntries;)this._split(a,e),e--;this._adjustParentBBoxes(i,a,e)},_split:function(t,e){var r=t[e],n=r.children.length,i=this._minEntries;this._chooseSplitAxis(r,i,n);var a=this._chooseSplitIndex(r,i,n),s=g(r.children.splice(a,r.children.length-a));s.height=r.height,s.leaf=r.leaf,o(r,this.toBBox),o(s,this.toBBox),e?t[e-1].children.push(s):this._splitRoot(r,s)},_splitRoot:function(t,e){this.data=g([t,e]),this.data.height=t.height+1,this.data.leaf=!1,o(this.data,this.toBBox)},_chooseSplitIndex:function(t,e,r){var n,i,a,o,l,h,c,p,f,d,g,_,m,y;for(h=c=1/0,n=e;n<=r-e;n++)f=i=s(t,0,n,this.toBBox),d=a=s(t,n,r,this.toBBox),g=Math.max(f.minX,d.minX),_=Math.max(f.minY,d.minY),m=Math.min(f.maxX,d.maxX),y=Math.min(f.maxY,d.maxY),o=Math.max(0,m-g)*Math.max(0,y-_),l=u(i)+u(a),ot[0]&&(e[0]=t[0]),e[1]>t[1]&&(e[1]=t[1]),e[2]t.length)&&(e=t.length);for(var r=0,n=new Array(e);rt.length)&&(e=t.length);for(var r=0,n=new Array(e);rt.length)&&(e=t.length);for(var r=0,n=new Array(e);r=u.length?void 0:o+1),l!==h){var p=u[h],f=u[l];!0!==this.options.hideMiddleMarkers&&this._createMiddleMarker(p,f)}u.splice(o,1),this._fireEdit(),this._layer.fire("pm:vertexremoved",{layer:this._layer,marker:r,indexPath:a})}},findDeepMarkerIndex:function(t,e){var r;t.some(function t(n){return function(i,a){var o=n.concat(a);return i._leaflet_id===e._leaflet_id?(r=o,!0):Array.isArray(i)&&i.some(t(o))}}([]));var n={};return r&&(n={indexPath:r,index:r[r.length-1],parentPath:r.slice(0,r.length-1)}),n},updatePolygonCoordsFromMarkerDrag:function(t){var e=this._layer.getLatLngs(),r=t.getLatLng(),n=this.findDeepMarkerIndex(this._markers,t),i=n.indexPath,a=n.index,o=n.parentPath;(1
+
+
@@ -16,6 +18,7 @@