/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package de.cismet.cids.custom.switchon.gui;
import com.vividsolutions.jts.geom.Geometry;
import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
import edu.umd.cs.piccolo.event.PInputEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import de.cismet.cids.custom.switchon.SwitchOnConstants;
import de.cismet.cids.custom.switchon.gui.utils.CismapUtils;
import de.cismet.cids.dynamics.CidsBean;
import de.cismet.cids.dynamics.CidsBeanStore;
import de.cismet.cismap.commons.BoundingBox;
import de.cismet.cismap.commons.CrsTransformer;
import de.cismet.cismap.commons.XBoundingBox;
import de.cismet.cismap.commons.features.DefaultStyledFeature;
import de.cismet.cismap.commons.features.Feature;
import de.cismet.cismap.commons.features.StyledFeature;
import de.cismet.cismap.commons.gui.MappingComponent;
import de.cismet.cismap.commons.gui.layerwidget.ActiveLayerModel;
import de.cismet.cismap.commons.interaction.CismapBroker;
import de.cismet.cismap.commons.raster.wms.simple.SimpleWMS;
import de.cismet.cismap.commons.raster.wms.simple.SimpleWmsGetMapUrl;
/**
* Panel which contains a mapping component.
*
* @author Gilles Baatz
* @version $Revision$, $Date$
*/
public class PreviewMapPanel extends javax.swing.JPanel implements CidsBeanStore {
//~ Static fields/initializers ---------------------------------------------
private static final transient org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(
PreviewMapPanel.class);
//~ Instance fields --------------------------------------------------------
private final MappingComponent previewMap;
private CidsBean cidsBean;
private final StyledFeature previewGeometry = new DefaultStyledFeature();
private String geoFieldPropertyKey = "";
private boolean purePreviewMap = true;
//~ Constructors -----------------------------------------------------------
/**
* Creates new form PreviewMapPanel.
*/
public PreviewMapPanel() {
initComponents();
previewMap = new MappingComponent();
this.add(previewMap, BorderLayout.CENTER);
}
//~ Methods ----------------------------------------------------------------
/**
* This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The
* content of this method is always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new java.awt.BorderLayout());
} // </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
/**
* DOCUMENT ME!
*/
private void initMap() {
if (cidsBean != null) {
final Object geoObj = cidsBean.getProperty(geoFieldPropertyKey);
Geometry tmpPureGeom = null;
if (geoObj != null) {
tmpPureGeom = CrsTransformer.transformToGivenCrs((Geometry)geoObj,
SwitchOnConstants.getInstance().SRS_SERVICE);
}
final Geometry pureGeom = tmpPureGeom;
final Runnable mapRunnable = new Runnable() {
@Override
public void run() {
final ActiveLayerModel mappingModel = new ActiveLayerModel();
mappingModel.setSrs(SwitchOnConstants.getInstance().SRS_SERVICE);
mappingModel.addHome(getBoundingBox(pureGeom));
final SimpleWMS swms = new SimpleWMS(new SimpleWmsGetMapUrl(
SwitchOnConstants.getInstance().MAP_CALL_STRING));
swms.setName("Spatial Coverage");
previewGeometry.setGeometry(pureGeom);
previewGeometry.setFillingPaint(new Color(1, 0, 0, 0.5f));
previewGeometry.setLineWidth(3);
previewGeometry.setLinePaint(new Color(1, 0, 0, 1f));
// add the raster layer to the model
mappingModel.addLayer(swms);
// set the model
previewMap.setMappingModel(mappingModel);
// initial positioning of the map
final int duration = previewMap.getAnimationDuration();
previewMap.setAnimationDuration(0);
previewMap.gotoInitialBoundingBox();
// interaction mode
previewMap.setInteractionMode(MappingComponent.ZOOM);
// finally when all configurations are done ...
previewMap.unlock();
if (purePreviewMap) {
previewMap.addCustomInputListener("MUTE", new PBasicInputEventHandler() {
@Override
public void mouseClicked(final PInputEvent evt) {
if (evt.getClickCount() > 1) {
final CidsBean bean = cidsBean;
CismapUtils.switchToCismapMap();
CismapUtils.addBeanGeomAsFeatureToCismapMap(bean, false);
}
}
});
previewMap.setInteractionMode("MUTE");
}
previewMap.getFeatureCollection().addFeature(previewGeometry);
previewMap.setAnimationDuration(duration);
}
};
if (EventQueue.isDispatchThread()) {
mapRunnable.run();
} else {
EventQueue.invokeLater(mapRunnable);
}
}
}
/**
* DOCUMENT ME!
*
* @param geom DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private XBoundingBox getBoundingBox(final Geometry geom) {
if (geom == null) {
final String srsCode = CismapBroker.getInstance()
.getMappingComponent()
.getMappingModel()
.getSrs()
.getCode();
final BoundingBox initb = CismapBroker.getInstance().getMappingComponent().getInitialBoundingBox();
return new XBoundingBox(initb.getX1(),
initb.getY1(),
initb.getX2(),
initb.getY2(),
srsCode,
CismapBroker.getInstance().getMappingComponent().getMappingModel().getSrs().isMetric());
}
double buffer;
if (isSmallGeom(geom)) {
final XBoundingBox box = new XBoundingBox(geom);
final double diagonalLength = Math.sqrt((box.getWidth() * box.getWidth())
+ (box.getHeight() * box.getHeight()));
if (LOG.isDebugEnabled()) {
LOG.debug("Buffer for map: " + diagonalLength);
}
buffer = diagonalLength;
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("SwitchOnConstants.Commons.GeoBUffer: " + SwitchOnConstants.getInstance().GEO_BUFFER);
}
buffer = SwitchOnConstants.getInstance().GEO_BUFFER;
}
final XBoundingBox bufferedBox;
try {
bufferedBox = new XBoundingBox(geom.getEnvelope().buffer(
buffer));
} catch (NullPointerException npe) {
LOG.error(
"NPE in the constructor of XBoundingBox. This happens if a renderer/editor is started with DevelopmentTools.",
npe);
return null;
}
return new XBoundingBox(
bufferedBox.getX1(),
bufferedBox.getY1(),
bufferedBox.getX2(),
bufferedBox.getY2(),
SwitchOnConstants.getInstance().SRS_SERVICE,
true);
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public Geometry getGeometry() {
Geometry geom = null;
for (final Feature f : previewMap.getFeatureCollection().getAllFeatures()) {
final Geometry g = f.getGeometry();
if (g != null) {
geom = g;
break;
}
}
return geom;
}
/**
* DOCUMENT ME!
*
* @param geometry DOCUMENT ME!
*/
public void setGeometry(final Geometry geometry) {
initMap();
// remove all features from the map
final List<Feature> featuresToRemove = new ArrayList<Feature>();
for (final Feature f : previewMap.getFeatureCollection().getAllFeatures()) {
featuresToRemove.add(f);
}
previewMap.getFeatureCollection().removeFeatures(featuresToRemove);
if (geometry != null) {
final StyledFeature dsf = new DefaultStyledFeature();
dsf.setGeometry(geometry);
dsf.setFillingPaint(new Color(1, 0, 0, 0.5f));
dsf.setLineWidth(3);
dsf.setLinePaint(new Color(1, 0, 0, 1f));
dsf.setEditable(true);
final XBoundingBox box;
try {
box = new XBoundingBox(geometry.getEnvelope().buffer(
SwitchOnConstants.getInstance().GEO_BUFFER));
} catch (NullPointerException npe) {
LOG.error(
"NPE in the constructor of XBoundingBox. This happens if a renderer/editor is started with DevelopmentTools.",
npe);
return;
}
if (previewMap.getMappingModel() != null) {
((ActiveLayerModel)previewMap.getMappingModel()).addHome(box);
previewMap.gotoInitialBoundingBox();
} else {
LOG.error(
"previewMap.getMappingModel() is null, can not set initial bounding box",
new NullPointerException());
}
previewMap.getFeatureCollection().addFeature(dsf);
}
}
/**
* Returns true if {@code pureGeom} is in EPSG:4326 and the difference of the X coordinates or of the Y coordinates
* of its bounding box is below 1.
*
* @param pureGeom DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private boolean isSmallGeom(final Geometry pureGeom) {
if (isEpsg4326(SwitchOnConstants.getInstance().SRS_SERVICE)) {
final XBoundingBox bbox = new XBoundingBox(pureGeom);
final boolean bigX = Math.abs(bbox.getX2() - bbox.getX1()) < 1;
final boolean bigY = Math.abs(bbox.getY2() - bbox.getY1()) < 1;
return bigX || bigY;
} else {
return false;
}
}
/**
* DOCUMENT ME!
*
* @param srsService DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private boolean isEpsg4326(final String srsService) {
return "EPSG:4326".equals(srsService);
}
@Override
public CidsBean getCidsBean() {
return cidsBean;
}
@Override
public void setCidsBean(final CidsBean cidsBean) {
this.cidsBean = cidsBean;
initMap();
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public String getGeoFieldPropertyKey() {
return geoFieldPropertyKey;
}
/**
* DOCUMENT ME!
*
* @param geoFieldPropertyKey DOCUMENT ME!
*/
public void setGeoFieldPropertyKey(final String geoFieldPropertyKey) {
this.geoFieldPropertyKey = geoFieldPropertyKey;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public MappingComponent getMappingComponent() {
return previewMap;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public boolean isPurePreviewMap() {
return purePreviewMap;
}
/**
* The map is only for preview purposes. No further interaction is needed. On double click on the map, a switch the
* main Cismap happens.
*
* @param purePreviewMap DOCUMENT ME!
*/
public void setPurePreviewMap(final boolean purePreviewMap) {
this.purePreviewMap = purePreviewMap;
}
}