package com.revolsys.swing.map.layer.raster; import java.awt.Dimension; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Arrays; import java.util.List; import org.jdesktop.swingx.table.TableColumnExt; import com.revolsys.geometry.model.BoundingBox; import com.revolsys.geometry.model.Geometry; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.raster.GeoreferencedImage; import com.revolsys.raster.MappedLocation; import com.revolsys.swing.action.enablecheck.EnableCheck; import com.revolsys.swing.action.enablecheck.ObjectPropertyEnableCheck; import com.revolsys.swing.field.Slider; import com.revolsys.swing.map.layer.Project; import com.revolsys.swing.menu.MenuFactory; import com.revolsys.swing.menu.Menus; import com.revolsys.swing.table.BaseJTable; import com.revolsys.swing.table.NumberTableCellRenderer; import com.revolsys.swing.table.TablePanel; import com.revolsys.swing.table.object.ObjectListTable; import com.revolsys.swing.table.object.ObjectListTableModel; import com.revolsys.swing.toolbar.ToolBar; import com.revolsys.util.Property; public class TiePointsPanel extends TablePanel implements PropertyChangeListener { private static final List<String> COLUMN_NAMES = Arrays.asList("#", "sourcePixelX", "sourcePixelY", "targetPointX", "targetPointY"); private static final long serialVersionUID = 1L; private static final List<String> TITLES = Arrays.asList("#", "Source Pixel X", "Source Pixel Y", "Target Point X", "Target Point Y"); private static final List<Class<?>> CLASSES = Arrays.asList(Integer.class, Integer.class, Integer.class, Double.class, Double.class); private final GeoreferencedImageLayer layer; private final Slider opacityField; public TiePointsPanel(final GeoreferencedImageLayer layer) { super(new ObjectListTable<>(layer.getImage().getTiePoints(), COLUMN_NAMES, TITLES, CLASSES)); this.layer = layer; final BaseJTable table = getTable(); final TableColumnExt column1 = table.getColumnExt(0); column1.setMinWidth(30); column1.setWidth(30); column1.setMaxWidth(30); for (int i = 3; i < table.getColumnCount(); i++) { final TableColumnExt column = table.getColumnExt(i); column.setMinWidth(150); column.setCellRenderer(new NumberTableCellRenderer("#,###.000")); } final EnableCheck editableEnableCheck = new ObjectPropertyEnableCheck(layer, "editable"); final MenuFactory menu = getTableModel().getMenu(); menu.addMenuItemTitleIcon("zoom", "Zoom to Tie Point", "magnifier_zoom_selected", this::zoomToTiePoint); menu.addMenuItemTitleIcon("record", "Delete Tie Point", "table_row_delete", editableEnableCheck, this::deleteTiePoint); final ToolBar toolBar = getToolBar(); final MenuFactory menuFactory = MenuFactory.findMenu(layer); if (menuFactory != null) { toolBar.addButtonTitleIcon("menu", "Layer Menu", "menu", () -> menuFactory.showMenu(layer, this, 10, 10)); } Menus.<GeoreferencedImageLayer> addMenuItem(menu, "zoom", "Zoom to Layer", "magnifier", GeoreferencedImageLayer::zoomToLayer, true); toolBar.addButton("zoom", "Zoom to Layer", "magnifier", (EnableCheck)null, layer::zoomToLayer); toolBar.addButton("edit", "Fit to Screen", "arrow_out", editableEnableCheck, layer::fitToViewport); this.opacityField = new Slider("opacity", 0, 256, layer.getOpacity()); this.opacityField.setMajorTickSpacing(64); this.opacityField.setMinorTickSpacing(16); this.opacityField.setPaintTicks(true); Property.addListener(this.opacityField, this); this.opacityField.setMaximumSize(new Dimension(100, 25)); toolBar.addComponent("edit", this.opacityField); Property.addListener(layer, "opacity", this); } public void deleteTiePoint() { final MappedLocation tiePoint = getEventRowObject(); this.layer.deleteTiePoint(tiePoint); } protected MappedLocation getEventRowObject() { final ObjectListTableModel<MappedLocation> model = getTableModel(); final int row = getEventRow(); final MappedLocation object = model.getObject(row); return object; } public GeoreferencedImage getImage() { return getLayer().getImage(); } public GeoreferencedImageLayer getLayer() { return this.layer; } public List<MappedLocation> getTiePoints() { return getImage().getTiePoints(); } @Override public void propertyChange(final PropertyChangeEvent event) { final String propertyName = event.getPropertyName(); if ("opacity".equals(propertyName)) { final Integer opacity = (Integer)event.getNewValue(); if (opacity != null) { if (event.getSource() == this.opacityField) { this.layer.setOpacity(opacity); } else { this.opacityField.setValue(opacity); } } } } @Override public void removeNotify() { super.removeNotify(); Property.removeListener(this.layer, "opacity", this); } public void zoomToTiePoint() { final MappedLocation object = getEventRowObject(); final GeoreferencedImage image = this.layer.getImage(); final Geometry geometry = object.getSourceToTargetLine(image, this.layer.getBoundingBox(), !this.layer.isShowOriginalImage()); if (geometry != null) { final Project project = Project.get(); final GeometryFactory geometryFactory = project.getGeometryFactory(); final BoundingBox boundingBox = geometry.getBoundingBox() .convert(geometryFactory) .expand(200); project.setViewBoundingBox(boundingBox); } } }