package org.esa.snap.rcp.actions.vector; import org.esa.snap.core.dataio.geometry.VectorDataNodeReader; import org.esa.snap.core.datamodel.GeometryDescriptor; import org.esa.snap.core.datamodel.PlacemarkDescriptor; import org.esa.snap.core.datamodel.PlacemarkDescriptorRegistry; import org.esa.snap.core.datamodel.Product; import org.esa.snap.core.util.FeatureUtils; import org.esa.snap.rcp.SnapApp; import org.esa.snap.rcp.actions.AbstractSnapAction; import org.esa.snap.ui.ModalDialog; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.referencing.crs.CoordinateReferenceSystem; import javax.swing.SwingUtilities; import java.lang.reflect.InvocationTargetException; import java.util.List; /** * @author olafd * @author Thomas Storm */ abstract class AbstractImportVectorDataNodeAction extends AbstractSnapAction { protected FeatureUtils.FeatureCrsProvider crsProvider; protected VectorDataNodeReader.PlacemarkDescriptorProvider placemarkDescriptorProvider; private int featureCrsDialogResult; protected AbstractImportVectorDataNodeAction() { crsProvider = new MyFeatureCrsProvider(); placemarkDescriptorProvider = new MyPlacemarkDescriptorProvider(); } private class MyPlacemarkDescriptorProvider implements VectorDataNodeReader.PlacemarkDescriptorProvider { @Override public PlacemarkDescriptor getPlacemarkDescriptor(SimpleFeatureType simpleFeatureType) { PlacemarkDescriptorRegistry placemarkDescriptorRegistry = PlacemarkDescriptorRegistry.getInstance(); if (simpleFeatureType.getUserData().containsKey(PlacemarkDescriptorRegistry.PROPERTY_NAME_PLACEMARK_DESCRIPTOR)) { String placemarkDescriptorClass = simpleFeatureType.getUserData().get(PlacemarkDescriptorRegistry.PROPERTY_NAME_PLACEMARK_DESCRIPTOR).toString(); PlacemarkDescriptor placemarkDescriptor = placemarkDescriptorRegistry.getPlacemarkDescriptor(placemarkDescriptorClass); if (placemarkDescriptor != null) { return placemarkDescriptor; } } List<PlacemarkDescriptor> validPlacemarkDescriptors = placemarkDescriptorRegistry.getPlacemarkDescriptors(simpleFeatureType); if (validPlacemarkDescriptors.size() == 1) { return validPlacemarkDescriptors.get(0); } if (featureCrsDialogResult == ModalDialog.ID_OK) { TypeDialog typeDialog = new TypeDialog(SnapApp.getDefault().getMainFrame(), simpleFeatureType); final int dialogResult = typeDialog.show(); if (dialogResult == ModalDialog.ID_OK) { return typeDialog.getPlacemarkDescriptor(); } else if (dialogResult == ModalDialog.ID_CANCEL) { typeDialog.close(); return null; } } else { return null; } return PlacemarkDescriptorRegistry.getInstance().getPlacemarkDescriptor(GeometryDescriptor.class); } } private class MyFeatureCrsProvider implements FeatureUtils.FeatureCrsProvider { @Override public CoordinateReferenceSystem getFeatureCrs(final Product product) { if (product.getSceneCRS() == Product.DEFAULT_IMAGE_CRS) { return Product.DEFAULT_IMAGE_CRS; } final CoordinateReferenceSystem[] featureCrsBuffer = new CoordinateReferenceSystem[1]; Runnable runnable = () -> featureCrsBuffer[0] = promptForFeatureCrs(product); if (!SwingUtilities.isEventDispatchThread()) { try { SwingUtilities.invokeAndWait(runnable); } catch (InterruptedException | InvocationTargetException e) { throw new RuntimeException(e); } } else { runnable.run(); } CoordinateReferenceSystem featureCrs = featureCrsBuffer[0]; return featureCrs != null ? featureCrs : DefaultGeographicCRS.WGS84; } @Override public boolean clipToProductBounds() { return true; } private CoordinateReferenceSystem promptForFeatureCrs(Product product) { final FeatureCrsDialog dialog = new FeatureCrsDialog(product, "Import " + getVectorDataType() + " Data"); featureCrsDialogResult = dialog.show(); if (featureCrsDialogResult == ModalDialog.ID_OK) { return dialog.getFeatureCrs(); } return DefaultGeographicCRS.WGS84; } } protected abstract String getDialogTitle(); protected abstract String getVectorDataType(); }