package com.revolsys.swing.map.layer.elevation.tin;
import java.beans.PropertyChangeEvent;
import java.util.Map;
import com.revolsys.collection.map.MapEx;
import com.revolsys.elevation.tin.TriangulatedIrregularNetwork;
import com.revolsys.geometry.model.BoundingBox;
import com.revolsys.geometry.model.GeometryFactory;
import com.revolsys.io.FileUtil;
import com.revolsys.io.IoFactory;
import com.revolsys.io.map.MapObjectFactoryRegistry;
import com.revolsys.logging.Logs;
import com.revolsys.raster.GeoreferencedImageReadFactory;
import com.revolsys.spring.resource.Resource;
import com.revolsys.swing.Icons;
import com.revolsys.swing.SwingUtil;
import com.revolsys.swing.component.BasePanel;
import com.revolsys.swing.component.TabbedValuePanel;
import com.revolsys.swing.component.ValueField;
import com.revolsys.swing.layout.GroupLayouts;
import com.revolsys.swing.map.layer.AbstractLayer;
import com.revolsys.swing.map.layer.Project;
import com.revolsys.swing.menu.MenuFactory;
import com.revolsys.swing.menu.Menus;
import com.revolsys.util.Property;
public class TriangulatedIrregularNetworkLayer extends AbstractLayer {
public static final String J_TYPE = "triangulatedIrregularNetworkLayer";
static {
final MenuFactory menu = MenuFactory.getMenu(TriangulatedIrregularNetworkLayer.class);
menu.addGroup(0, "table");
menu.addGroup(2, "edit");
Menus.<TriangulatedIrregularNetworkLayer> addMenuItem(menu, "refresh", "Reload from File",
Icons.getIconWithBadge("page", "refresh"), TriangulatedIrregularNetworkLayer::revertDo, true);
menu.deleteMenuItem("refresh", "Refresh");
}
public static void mapObjectFactoryInit() {
MapObjectFactoryRegistry.newFactory(J_TYPE, "Triangulated Irregular Network Layer",
TriangulatedIrregularNetworkLayer::new);
}
private TriangulatedIrregularNetwork tin;
private Resource resource;
private String url;
public TriangulatedIrregularNetworkLayer(final Map<String, ? extends Object> properties) {
super(J_TYPE);
setProperties(properties);
setSelectSupported(false);
setQuerySupported(false);
setReadOnly(true);
final TriangulatedIrregularNetworkLayerRenderer renderer = new TriangulatedIrregularNetworkLayerRenderer(
this);
setRenderer(renderer);
setIcon(Icons.getIcon("picture"));
}
@Override
public BoundingBox getBoundingBox() {
final TriangulatedIrregularNetwork elevationModel = getTin();
if (elevationModel == null) {
return BoundingBox.empty();
} else {
return elevationModel.getBoundingBox();
}
}
@Override
public BoundingBox getBoundingBox(final boolean visibleLayersOnly) {
if (isExists() && (isVisible() || !visibleLayersOnly)) {
return getBoundingBox();
} else {
return getGeometryFactory().newBoundingBoxEmpty();
}
}
@Override
public GeometryFactory getGeometryFactory() {
if (this.tin == null) {
return getBoundingBox().getGeometryFactory();
} else {
return this.tin.getGeometryFactory();
}
}
public TriangulatedIrregularNetwork getTin() {
return this.tin;
}
@Override
protected boolean initializeDo() {
final String url = getProperty("url");
if (Property.hasValue(url)) {
this.url = url;
this.resource = Resource.getResource(url);
revertDo();
return this.tin != null;
} else {
Logs.error(this, "Layer definition does not contain a 'url' property");
return false;
}
}
@Override
public boolean isVisible() {
return super.isVisible() || isEditable();
}
@Override
public TabbedValuePanel newPropertiesPanel() {
final TabbedValuePanel propertiesPanel = super.newPropertiesPanel();
return propertiesPanel;
}
@Override
protected ValueField newPropertiesTabGeneralPanelSource(final BasePanel parent) {
final ValueField panel = super.newPropertiesTabGeneralPanelSource(parent);
if (this.url.startsWith("file:")) {
final String fileName = this.url.replaceFirst("file:(//)?", "");
SwingUtil.addLabelledReadOnlyTextField(panel, "File", fileName);
} else {
SwingUtil.addLabelledReadOnlyTextField(panel, "URL", this.url);
}
final String fileNameExtension = FileUtil.getFileNameExtension(this.url);
if (Property.hasValue(fileNameExtension)) {
SwingUtil.addLabelledReadOnlyTextField(panel, "File Extension", fileNameExtension);
final GeoreferencedImageReadFactory factory = IoFactory
.factoryByFileExtension(GeoreferencedImageReadFactory.class, fileNameExtension);
if (factory != null) {
SwingUtil.addLabelledReadOnlyTextField(panel, "File Type", factory.getName());
}
}
GroupLayouts.makeColumns(panel, 2, true);
return panel;
}
@Override
public void propertyChange(final PropertyChangeEvent event) {
super.propertyChange(event);
final String propertyName = event.getPropertyName();
if ("hasChanges".equals(propertyName)) {
final TriangulatedIrregularNetwork image = getTin();
if (event.getSource() == image) {
image.writeTriangulatedIrregularNetwork();
}
}
}
protected void revertDo() {
if (this.resource != null) {
TriangulatedIrregularNetwork tin = null;
try {
this.tin = null;
final Resource resource = Resource.getResource(this.url);
if (resource.exists()) {
tin = TriangulatedIrregularNetwork.newTriangulatedIrregularNetwork(resource);
if (tin == null) {
Logs.error(TriangulatedIrregularNetworkLayer.class, "Cannot load TIN: " + this.url);
}
} else {
Logs.error(TriangulatedIrregularNetworkLayer.class, "TIN does not exist: " + this.url);
}
} catch (final Throwable e) {
Logs.error(TriangulatedIrregularNetworkLayer.class, "Unable to load TIN: " + this.url, e);
} finally {
setTin(tin);
}
firePropertyChange("hasChanges", true, false);
}
}
public void setTin(final TriangulatedIrregularNetwork elevationModel) {
final TriangulatedIrregularNetwork old = this.tin;
Property.removeListener(this.tin, this);
this.tin = elevationModel;
if (elevationModel == null) {
setExists(false);
} else {
setExists(true);
Property.addListener(elevationModel, this);
}
firePropertyChange("elevationModel", old, this.tin);
}
@Override
public MapEx toMap() {
final MapEx map = super.toMap();
map.remove("querySupported");
map.remove("selectSupported");
map.remove("editable");
map.remove("readOnly");
map.remove("showOriginalImage");
map.remove("imageSettings");
addToMap(map, "url", this.url);
return map;
}
@Override
public void zoomToLayer() {
final Project project = getProject();
final GeometryFactory geometryFactory = project.getGeometryFactory();
final BoundingBox layerBoundingBox = getBoundingBox();
BoundingBox boundingBox = layerBoundingBox;
boundingBox = boundingBox.convert(geometryFactory).expandPercent(0.1).clipToCoordinateSystem();
project.setViewBoundingBox(boundingBox);
}
}