import business.*;
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.geom.Point;
import net.miginfocom.swing.MigLayout;
import org.geotools.data.FeatureSource;
import org.geotools.data.memory.MemoryFeatureCollection;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.SchemaException;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureImpl;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.styling.SLD;
import org.geotools.styling.Style;
import org.geotools.swing.JMapPane;
import org.geotools.swing.event.MapMouseAdapter;
import org.geotools.swing.event.MapPaneEvent;
import org.geotools.swing.event.MapPaneListener;
import org.opengis.feature.Attribute;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.referencing.operation.TransformException;
import utilities.Logger;
import views.DataBasePanelView;
import views.PointPopUpMenu;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import java.util.*;
/**
* Created with IntelliJ IDEA.
* User: chernyshovyuriy
* Date: 3/24/13
* Time: 4:17 PM
*/
public class MainView extends JFrame implements IOpenFile, IPointPopUpMenuSelected {
private JPanel mainPanel;
private JPanel mapView;
private JPanel controlsView;
private JTextField shapeFilePath;
private JTextArea informationLabel;
private JButton browseShapeFileBtn;
private JButton routeCalculateStartBtn;
private JLabel shapeFileRenderingProgressLabel;
private JButton workWithDBBtn;
private MapContent map;
private SimpleFeatureSource simpleFeatureSource;
private ArrayList<Point> points;
private Point startPoint;
public MainView() {
// Precautionary - to prevent axis flipping!
System.setProperty("org.geotools.referencing.forceXY", "true");
setTitle("Route Calculator");
setContentPane(mainPanel);
setSize(1000, 600);
setVisible(true);
setLocationRelativeTo(null);
points = new ArrayList<Point>();
browseShapeFileBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
ShapeFileProcessor shapeFileProcessor = new ShapeFileProcessor();
shapeFileProcessor.getShapeFile(MainView.this);
}
});
routeCalculateStartBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
routeCalculateStartBtn.setEnabled(Boolean.FALSE);
workWithDBBtn.setEnabled(Boolean.FALSE);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
calculateRoute();
}
}, "CalculateRouteThread");
try {
thread.join();
} catch (InterruptedException e1) {
Logger.e("CalculateRouteThread join", e1);
}
thread.start();
}
});
workWithDBBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new DataBasePanelView();
}
});
}
public void onStartPointItemSelected(java.awt.Point screenPos, Coordinate pointCoordinate) {
Logger.i("Start Point selected");
informationLabel.setText("Now, select any point(s) and press 'Start Calculate'");
startPoint = getPointFromCoordinates(pointCoordinate);
addPointToMap(startPoint);
/*Rectangle screenRect = new Rectangle(screenPos.x - 1, screenPos.y - 1, 3, 3);
CoordinateReferenceSystem worldCRS = simpleFeatureSource.getSchema().getCoordinateReferenceSystem();
// Transform the screen rectangle into a bounding box in the
// coordinate reference system of our map content.
AffineTransform screenToWorld = ((JMapPane) mapView.getComponent(0)).getScreenToWorldTransform();
Rectangle2D worldRect = screenToWorld.createTransformedShape(screenRect).getBounds2D();
ReferencedEnvelope worldBBox = new ReferencedEnvelope(worldRect, worldCRS);
// transform from world to target CRS
SimpleFeatureType schema = simpleFeatureSource.getSchema();
CoordinateReferenceSystem targetCRS = schema.getCoordinateReferenceSystem();
String geometryAttributeName = schema.getGeometryDescriptor().getLocalName();
ReferencedEnvelope bbox = null;
try {
bbox = worldBBox.transform(targetCRS, true, 10);
} catch (TransformException e) {
} catch (FactoryException e) {
}
FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
// Option 1 BBOX
Filter filter = ff.bbox(ff.property(geometryAttributeName), bbox);
// Option 2 Intersects
// Filter filter = ff.intersects(ff.property(geometryAttributeName), ff.literal(bbox));
try {
parseFeatureSource(simpleFeatureSource.getFeatures(filter));
} catch (IOException e) {
}*/
}
public void onPointItemSelected(java.awt.Point screenPos, Coordinate pointCoordinate) {
Logger.i("Point selected");
Point point = getPointFromCoordinates(pointCoordinate);
points.add(point);
addPointToMap(point);
routeCalculateStartBtn.setEnabled(Boolean.TRUE);
workWithDBBtn.setEnabled(Boolean.TRUE);
}
public void onFileOpen(File file) {
if (file != null) {
shapeFileRenderingProgressLabel.setVisible(Boolean.TRUE);
shapeFilePath.setText(file.getName());
ShapeFileProcessor shapeFileProcessor = new ShapeFileProcessor();
simpleFeatureSource = shapeFileProcessor.getSimpleFeatureSource(file);
createMap();
}
}
private void createMap() {
// TODO: set this cleaning procedure to the concrete method
// TODO: probably hold somewhere a reference to current MapContent
if (map != null) {
map.dispose();
map = null;
Component[] components = mapView.getComponents();
for (Component component : components) {
mapView.remove(component);
}
resetToNewShape();
}
// Create a map content and add our file to it
map = new MapContent();
map.setTitle("Map");
/*try {
parseFeatureSource(simpleFeatureSource.getFeatures());
} catch (IOException e) {
}*/
if (simpleFeatureSource == null) {
Logger.w("Roads Feature source is NULL");
informationLabel.setText("Selected file is not a shape format.");
shapeFileRenderingProgressLabel.setVisible(Boolean.FALSE);
return;
}
informationLabel.setText("Please, set Start point first.");
Style style = SLD.createSimpleStyle(simpleFeatureSource.getSchema(), Color.GRAY);
Layer layer = new FeatureLayer(simpleFeatureSource, style);
map.addLayer(layer);
JMapPane mapPane = new JMapPane(map);
mapPane.setBackground(Color.WHITE);
mapPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
mapPane.addMapPaneListener(new MapPaneListener() {
@Override
public void onNewMapContent(MapPaneEvent mapPaneEvent) {
//Logger.d("Map Pane New");
}
@Override
public void onDisplayAreaChanged(MapPaneEvent mapPaneEvent) {
//Logger.d("Map Pane Display Area Change");
}
@Override
public void onRenderingStarted(MapPaneEvent mapPaneEvent) {
//Logger.d("Map Pane Rendering Start");
}
@Override
public void onRenderingStopped(MapPaneEvent mapPaneEvent) {
//Logger.d("Map Pane Rendering Stop");
shapeFileRenderingProgressLabel.setVisible(Boolean.FALSE);
}
});
/*
* We use the MigLayout manager to make it easy to manually code
* our UI design
*/
StringBuilder sb = new StringBuilder();
//if (!toolSet.isEmpty()) {
// sb.append("[]"); // fixed size
//}
sb.append("[grow]"); // map pane and optionally layer table fill space
//if (showStatusBar) {
// sb.append("[min!]"); // status bar height
//}
MigLayout migLayout = new MigLayout(
"wrap 1, insets 0", // layout constrains: 1 component per row, no insets
"[grow]", // column constraints: col grows when frame is re-sized
sb.toString());
mapView.setLayout(migLayout);
mapView.add(mapPane, "grow");
mapView.updateUI();
PointSelectedHelper pointSelectedHelper = new PointSelectedHelper();
// Create PopUp menu
PointPopUpMenu pointPopUpMenu = new PointPopUpMenu(pointSelectedHelper, MainView.this);
//Add listener to components that can bring up popup menus.
MapMouseAdapter popupListener = new MapMouseListener(pointPopUpMenu.getPopupMenu(), pointSelectedHelper);
mapPane.addMouseListener(popupListener);
}
private void resetToNewShape() {
points.clear();
startPoint = null;
}
private void calculateRoute() {
CalculateRoutes routeCalculator = new CalculateRoutes();
// build the network using the point of origin and the network data set
try {
routeCalculator.buildNetwork(simpleFeatureSource.getFeatures(), startPoint);
} catch (TransformException e1) {
Logger.e("Route Calc Error", e1);
} catch (IOException e1) {
Logger.e("Route Calc Error", e1);
}
int j;
boolean isSuccess = false;
for (j = 0; j < points.size(); j++) {
try {
if (routeCalculator.calculateRouteFeature(startPoint, points.get(j), j)) {
isSuccess = true;
}
} catch (SchemaException e1) {
Logger.e("Route Calc Error", e1);
} catch (TransformException e1) {
Logger.e("Route Calc Error", e1);
}
}
if (!isSuccess) {
Logger.i("Draw route error");
informationLabel.setText("Route drawn error");
routeCalculateStartBtn.setEnabled(Boolean.TRUE);
workWithDBBtn.setEnabled(Boolean.TRUE);
return;
}
FeatureSource<SimpleFeatureType, SimpleFeature> routeSource;
try {
routeSource = routeCalculator.getRouteFeatureSource();
Style style = SLD.createLineStyle(Color.RED, 3);
Layer layer = new FeatureLayer(routeSource, style);
map.addLayer(layer);
Logger.i("Draw route");
informationLabel.setText("Route has been drawn");
JOptionPane.showMessageDialog(MainView.this, "Route has been drawn");
//startPoint
} catch (IOException e1) {
Logger.e("Route Calc Error", e1);
}
routeCalculateStartBtn.setEnabled(Boolean.TRUE);
workWithDBBtn.setEnabled(Boolean.TRUE);
}
private Point getPointFromCoordinates(Coordinate coordinate) {
GeometryFactory geometryFactory = new GeometryFactory();
return geometryFactory.createPoint(coordinate);
}
private void addPointToMap(Point point) {
//the type, schema = ( name:String, classification:Integer, height:Double, location:Point)
SimpleFeatureType type = createPointFeatureType();
MemoryFeatureCollection memoryFeatureCollection = new MemoryFeatureCollection(type);
//create the builder
SimpleFeatureBuilder builder = new SimpleFeatureBuilder(type);
//add the values
builder.add(point);
//builder.add("City");
//build the feature with provided ID
SimpleFeature feature = builder.buildFeature(null);
memoryFeatureCollection.add(feature);
Style style = SLD.createPointStyle("Circle", Color.RED, Color.GREEN, 1, 10);
Layer layer = new FeatureLayer(memoryFeatureCollection, style);
map.addLayer(layer);
}
private SimpleFeatureType createPointFeatureType() {
SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
builder.setName("Destinations");
builder.setCRS(simpleFeatureSource.getSchema().getCoordinateReferenceSystem()); // Coordinate reference system
// add attributes in order
builder.add("the_geom", Point.class);
//builder.length(15).add("point_name", String.class); // 15 chars width for name field
return builder.buildFeatureType();
}
private void createUIComponents() {
// TODO: place custom component creation code here
}
private void parseFeatureSource(SimpleFeatureCollection features) {
try {
Logger.d("Features size: " + features.size());
SimpleFeatureIterator iterator = features.features();
SimpleFeatureImpl simpleFeature;
while (iterator.hasNext()) {
simpleFeature = (SimpleFeatureImpl) iterator.next();
if (simpleFeature != null) {
java.util.List list = (java.util.List) simpleFeature.getAttributes();
Collection<Properties> properties = (java.util.List) simpleFeature.getProperties();
//Logger.d("Feature " + list.size() + " " + properties.size());
/*for (int i = 0; i < list.size(); i++) {
if (list.get(i) != null) {
Logger.d("Feature " + list.get(i).toString());
}
if (list.get(i) instanceof Attribute) {
Logger.d("Feature " + (Attribute) list.get(i));
}
}*/
Iterator<Properties> iterator1 = properties.iterator();
Attribute attribute;
while (iterator1.hasNext()) {
attribute = (Attribute) iterator1.next();
if (attribute != null) {
Logger.d("Property " + attribute.getName() + ":" + attribute.getValue());
}
}
/* Map<Object, Object> objectMap = simpleFeature.getUserData();
Set<Map.Entry<Object, Object>> set = objectMap.entrySet();
Iterator<Map.Entry<Object, Object>> iterator1 = set.iterator();
while (iterator1.hasNext()) {
Logger.d("Feature " + iterator1.next());
}*/
}
break;
}
} catch (Throwable e) {
Logger.e("Get Features error", e);
}
}
/*private String getUTF8String(Object object) {
try {
byte[] utf8Bytes = object.toString().getBytes("UTF-8");
return new String(utf8Bytes, "UTF-8");
*//*StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < utf8Bytes.length; i++) {
stringBuilder.append(utf8Bytes[i]);
}
return stringBuilder.toString();*//*
} catch (UnsupportedEncodingException e) {
Logger.e("Get UTF8 Str error", e);
}
return "";
}*/
}