package org.netomi.tracker.ui; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.math3.util.FastMath; import org.netomi.tracker.model.Satellite; import org.netomi.tracker.model.TleEntry; import org.netomi.tracker.orekit.SatellitePropagation; import org.netomi.tracker.orekit.VisibilityEntry; import org.netomi.tracker.service.SatelliteService; import org.orekit.propagation.analytical.tle.TLE; import org.orekit.time.AbsoluteDate; import org.orekit.time.TimeScalesFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.vaadin.vol.Marker; import org.vaadin.vol.MarkerLayer; import org.vaadin.vol.OpenLayersMap; import org.vaadin.vol.OpenStreetMapLayer; import org.vaadin.vol.Point; import org.vaadin.vol.PolyLine; import org.vaadin.vol.Style; import org.vaadin.vol.StyleMap; import org.vaadin.vol.Vector; import org.vaadin.vol.VectorLayer; import org.vaadin.vol.VectorLayer.DrawingMode; import org.vaadin.vol.VectorLayer.SelectionMode; import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.util.BeanItem; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.terminal.ExternalResource; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; import com.vaadin.ui.Component; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Table; import com.vaadin.ui.Table.ColumnGenerator; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.themes.Runo; @Configurable(preConstruction = true) public class VisibilityScreen extends HorizontalLayout { private static final long serialVersionUID = -6709613234549226348L; @Autowired private transient SatelliteService satService; private TextField latitudeField; private TextField longitudeField; private Table visTable; private BeanItemContainer<VisibilityEntry> ic; private VectorLayer vectorLayer; private MarkerLayer markerLayer; private Map<Long, Component> visiblePasses = new HashMap<Long, Component>(); private Map<Long, Set<Component>> visibleMarkers = new HashMap<Long, Set<Component>>(); private TLE latestTLE; private double latestLat; private double latestLon; public VisibilityScreen() { setMargin(true); setSpacing(true); setSizeFull(); VerticalLayout vl = new VerticalLayout(); vl.setSpacing(true); vl.setSizeUndefined(); final SatelliteTable table = new SatelliteTable(new String[] { "catalogNumber", "commonName" }, new String[] { "Catalog Number", "Common Name" }, 5); table.setSizeUndefined(); vl.addComponent(table); // create the lat/lon fields and set them to a default location latitudeField = new TextField(); latitudeField.setCaption("Latitude"); latitudeField.setValue("50.84"); vl.addComponent(latitudeField); longitudeField = new TextField(); longitudeField.setCaption("Longitude"); longitudeField.setValue("4.35"); vl.addComponent(longitudeField); Button compute = new Button("Show", new Button.ClickListener() { private static final long serialVersionUID = -2433152978338766513L; public void buttonClick(ClickEvent event) { if (table.getValue() == null) { return; } Item item = table.getItem(table.getValue()); Long id = (Long) item.getItemProperty("catalogNumber").getValue(); Satellite sat = satService.getSatellite(id); TleEntry entry = satService.getLatestTleEntry(sat); vectorLayer.removeAllComponents(); markerLayer.removeAllComponents(); try { latestTLE = new TLE(entry.getLine1(), entry.getLine2()); AbsoluteDate startDate = new AbsoluteDate(new Date(), TimeScalesFactory.getUTC()); ic.removeAllItems(); latestLat = Double.valueOf((String) latitudeField.getValue()); latestLon = Double.valueOf((String) longitudeField.getValue()); // get visibilities for the next 5 days List<VisibilityEntry> entries = SatellitePropagation.getVisibilities(latestLat, latestLon, 0, FastMath.toRadians(10), latestTLE, startDate, 60L*60*24*5); ic.addAll(entries); } catch (Exception e) { e.printStackTrace(); } } }); compute.setWidth("100%"); compute.addStyleName(Runo.BUTTON_DEFAULT); compute.addStyleName(Runo.BUTTON_BIG); vl.addComponent(compute); visTable = new Table(); visTable.setSizeUndefined(); ic = new BeanItemContainer<VisibilityEntry>(VisibilityEntry.class); visTable.setContainerDataSource(ic); visTable.addGeneratedColumn("start", new ShortDateTimeColumnGenerator()); visTable.addGeneratedColumn("end", new ShortDateTimeColumnGenerator()); visTable.addGeneratedColumn("visible", new ColumnGenerator() { private static final long serialVersionUID = 9130845892092636484L; public Component generateCell(final Table source, final Object itemId, final Object columnId) { final CheckBox checkbox = new CheckBox(); checkbox.setValue(false); checkbox.setImmediate(true); checkbox.addListener(new CheckBox.ValueChangeListener() { private static final long serialVersionUID = -6410213284048446509L; public void valueChange(Property.ValueChangeEvent event) { @SuppressWarnings("unchecked") BeanItem<VisibilityEntry> item = (BeanItem<VisibilityEntry>) visTable.getItem(itemId); VisibilityEntry entry = item.getBean(); boolean show = (Boolean) event.getProperty().getValue(); checkbox.setValue(show); if (show) { addPass(entry); } else { Component comp = visiblePasses.get(entry.getStart().getTime()); if (comp != null) { vectorLayer.removeComponent(comp); for (Component c : visibleMarkers.get(entry.getStart().getTime())) { markerLayer.removeComponent(c); } markerLayer.requestRepaint(); } } } }); return checkbox; } }); visTable.setVisibleColumns(new String[] { "start", "end", "visible" }); visTable.setColumnHeaders(new String[] { "Start", "End", "Show" }); visTable.setColumnIcon("start", new ExternalResource("images/up.png")); visTable.setColumnIcon("end", new ExternalResource("images/dwn.png")); visTable.setColumnAlignment("visible", Table.ALIGN_CENTER); visTable.setPageLength(5); vl.addComponent(visTable); addComponent(vl); OpenLayersMap map = new OpenLayersMap(); map.setSizeFull(); map.setImmediate(true); // update extent and zoom to server as they change OpenStreetMapLayer osm = new OpenStreetMapLayer(); map.addLayer(osm); vectorLayer = new VectorLayer(); vectorLayer.setSelectionMode(SelectionMode.NONE); Style defaultStyle = new Style(); /* Set stroke color to green, otherwise like default style */ defaultStyle.extendCoreStyle("default"); defaultStyle.setStrokeColor("#00b963"); defaultStyle.setStrokeOpacity(0.5); defaultStyle.setStrokeWidth(4); Style selectStyle = new Style(); /* Set select color to blue, otherwise like default style */ selectStyle.extendCoreStyle("default"); selectStyle.setStrokeColor("#0063b9"); selectStyle.setStrokeOpacity(0.5); selectStyle.setStrokeWidth(4); StyleMap styleMap = new StyleMap(defaultStyle, selectStyle, null); // make selectStyle inherit attributes not explicitly set styleMap.setExtendDefault(true); vectorLayer.setStyleMap(styleMap); vectorLayer.setDrawindMode(DrawingMode.NONE); map.addLayer(vectorLayer); // Define a Marker Layer markerLayer = new MarkerLayer(); map.addLayer(markerLayer); addComponent(map); setExpandRatio(map, 1); } private void addPass(final VisibilityEntry entry) { try { SatellitePropagation.fillVisibilityEntry(latestLat, latestLon, 0, latestTLE, entry); Set<Component> markers = new HashSet<Component>(); List<Point> npoints = new LinkedList<Point>(); for (org.netomi.tracker.orekit.VisibilityEntry.Point pe : entry.getPoints()) { final double lat = pe.getLat(); final double lon = pe.getLon(); npoints.add(new Point(lon, lat)); } Vector line = new PolyLine(); line.setPoints(npoints.toArray(new Point[npoints.size()])); vectorLayer.addVector(line); visiblePasses.put(entry.getStart().getTime(), line); // add markers at start and end Point[] points = line.getPoints(); Marker startMarker = new Marker(points[0].getLon(), points[0].getLat()); startMarker.setIcon(new ExternalResource("images/up.png"), 14, 14); markerLayer.addMarker(startMarker); markers.add(startMarker); int lastIdx = points.length - 1; Marker endMarker = new Marker(points[lastIdx].getLon(), points[lastIdx].getLat()); endMarker.setIcon(new ExternalResource("images/dwn.png"), 14, 14); markerLayer.addMarker(endMarker); markers.add(endMarker); visibleMarkers.put(entry.getStart().getTime(), markers); } catch (Exception e) { e.printStackTrace(); } } }