nl.cloudfarming.client.geoviewer.jxmap.map.AbstractLineDrawingContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of geoviewer-jxmap Show documentation
Show all versions of geoviewer-jxmap Show documentation
AgroSense geoviewer JXMap implementation. Contains a map/geoviewer TopComponent based on the JXMap classes from swingx.
The newest version!
/**
* Copyright (C) 2008-2012 AgroSense Foundation.
*
* AgroSense is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* There are special exceptions to the terms and conditions of the GPLv3 as it is applied to
* this software, see the FLOSS License Exception
* .
*
* AgroSense is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AgroSense. If not, see .
*/
package nl.cloudfarming.client.geoviewer.jxmap.map;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.CoordinateSequence;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import nl.cloudfarming.client.geoviewer.SingleObjectLayer;
import org.jdesktop.swingx.JXMapViewer;
import org.jdesktop.swingx.mapviewer.GeoPosition;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
/**
*
* @author johan
*/
public abstract class AbstractLineDrawingContext implements DrawingContext {
protected final List coords = new ArrayList<>();
// FIXME: set WGS-84 SRID or CRS on factory
protected final GeometryFactory geometryFactory = new GeometryFactory();
private final AbstractLocationPicker locationPicker;
private PropertyChangeSupport propertyChangeSupport;
private SingleObjectLayer layer;
public AbstractLineDrawingContext(SingleObjectLayer layer, JXMapViewer mapViewer) {
this.layer = layer;
locationPicker = new AbstractLocationPicker(mapViewer, true) {
@Override
public boolean select(GeoPosition position) {
return addPoint(position);
}
};
locationPicker.start();
}
@Override
public SingleObjectLayer getLayer(){
return this.layer;
}
private boolean addPoint(GeoPosition position) {
Coordinate coord = new Coordinate(position.getLongitude(), position.getLatitude());
if (isValidLine(coord)) {
coords.add(coord);
pointAdded();
// notify panel & toolbar actions:
getPropertyChangeSupport().firePropertyChange(PROP_DRAWING_CONTEXT, null, null);
return true;
}
return false;
}
/**
* Check if adding the provided coordinate to the list will produce a valid line.
* The new segment must not intersect any of the existing ones.
*
* @param coord
* @return
*/
protected boolean isValidLine(Coordinate coord) {
int len = coords.size();
// number of points in LineString must be 0 or >= 2)
if (len < 2) {
return true;
}
CoordinateSequence coordSequence1 = new CoordinateArraySequence(coords.toArray(new Coordinate[len]));
CoordinateSequence coordSequence2 = new CoordinateArraySequence(new Coordinate[] {coords.get(len - 1), coord});
LineString lineString1 = new LineString(coordSequence1, geometryFactory);
LineString lineString2 = new LineString(coordSequence2, geometryFactory);
return !lineString1.crosses(lineString2);
}
private void removeLastPoint() {
if (!coords.isEmpty()) {
coords.remove(coords.size() - 1);
pointRemoved();
getPropertyChangeSupport().firePropertyChange(PROP_DRAWING_CONTEXT, null, null);
}
}
private void removeAllPoints() {
if (!coords.isEmpty()) {
coords.clear();
pointRemoved();
getPropertyChangeSupport().firePropertyChange(PROP_DRAWING_CONTEXT, null, null);
}
}
/*
* Alow subclasses to perform extra actions after points are added or removed
* (but before re-rendering), because there might be other objects in the
* scene depending on the drawn line.
*/
protected void pointAdded() {
}
protected void pointRemoved() {
}
protected void cleanup() {
if (locationPicker.isActive()) {
locationPicker.stop();
}
}
PropertyChangeSupport getPropertyChangeSupport() {
if (propertyChangeSupport == null){
propertyChangeSupport = new PropertyChangeSupport(this);
}
return propertyChangeSupport;
}
@Override
public void addPropertyChangeListener(PropertyChangeListener listener) {
getPropertyChangeSupport().addPropertyChangeListener(listener);
}
@Override
public void removePropertyChangeListener(PropertyChangeListener listener) {
getPropertyChangeSupport().removePropertyChangeListener(listener);
}
@Override
public void cancel() {
cleanup();
}
/**
* Create toolbar actions.
*
* @return
*/
@Override
public Action[] getActions() {
List actions = new ArrayList<>();
// toggle drawing/navigation:
actions.add(new DrawAction());
actions.add(new NavigateAction());
actions.add(new RemoveOneAction());
actions.add(new RemoveAllAction());
return actions.toArray(new Action[0]);
}
//
// toolbar actions:
//
@NbBundle.Messages({
"drawing_draw_action_name=Add points",
"drawing_draw_action_tooltip=Add points",
"drawing_draw_action_icon=nl/cloudfarming/client/geoviewer/jxmap/icons/draw_path16.png"})
private class DrawAction extends AbstractAction {
public DrawAction() {
putValue(SHORT_DESCRIPTION, Bundle.drawing_draw_action_tooltip());
putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(Bundle.drawing_draw_action_icon(), true));
setEnabled(!locationPicker.isActive());
locationPicker.addPropertyChangeListener(AbstractLocationPicker.PROP_ACTIVE, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
setEnabled(!locationPicker.isActive());
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
locationPicker.start();
}
}
@NbBundle.Messages({
"drawing_navigate_action_name=Navigate",
"drawing_navigate_action_tooltip=Navigate",
"drawing_navigate_action_icon=nl/cloudfarming/client/geoviewer/jxmap/icons/map16.png"})
private class NavigateAction extends AbstractAction {
public NavigateAction() {
putValue(SHORT_DESCRIPTION, Bundle.drawing_navigate_action_tooltip());
putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(Bundle.drawing_navigate_action_icon(), true));
setEnabled(locationPicker.isActive());
locationPicker.addPropertyChangeListener(AbstractLocationPicker.PROP_ACTIVE, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
setEnabled(locationPicker.isActive());
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
locationPicker.stop();
}
}
@NbBundle.Messages({
"drawing_remove_one_action_name=Remove one",
"drawing_remove_one_action_tooltip=Remove the last point",
"drawing_remove_one_action_icon=nl/cloudfarming/client/geoviewer/jxmap/icons/vector_delete16.png"})
private class RemoveOneAction extends AbstractAction {
public RemoveOneAction() {
putValue(SHORT_DESCRIPTION, Bundle.drawing_remove_one_action_tooltip());
putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(Bundle.drawing_remove_one_action_icon(), true));
setEnabled(coords.size() > 0);
AbstractLineDrawingContext.this.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
setEnabled(coords.size() > 0);
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
removeLastPoint();
}
}
@NbBundle.Messages({
"drawing_remove_all_action_name=Remove all",
"drawing_remove_all_action_tooltip=Remove all points",
"drawing_remove_all_action_icon=nl/cloudfarming/client/geoviewer/jxmap/icons/delete16.png"})
private class RemoveAllAction extends AbstractAction {
public RemoveAllAction() {
putValue(SHORT_DESCRIPTION, Bundle.drawing_remove_all_action_tooltip());
putValue(LARGE_ICON_KEY, ImageUtilities.loadImageIcon(Bundle.drawing_remove_all_action_icon(), true));
setEnabled(coords.size() > 0);
AbstractLineDrawingContext.this.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
setEnabled(coords.size() > 0);
}
});
}
@Override
public void actionPerformed(ActionEvent e) {
removeAllPoints();
}
}
}