/* * Copyright 2013 Serdar. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.fub.agg2graphui.layers; import com.infomatiq.jsi.rtree.RTree; import de.fub.agg2graph.structs.GPSPoint; import de.fub.agg2graph.structs.GPSSegment; import de.fub.agg2graph.structs.ILocation; import de.fub.agg2graph.ui.gui.RenderingOptions; import de.fub.agg2graphui.controller.AbstractLayer; import de.fub.mapviewer.ui.MapViewer; import gnu.trove.TIntProcedure; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.Area; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Properties; import org.jdesktop.swingx.mapviewer.GeoPosition; /** * * @author Serdar */ public class GPSSegmentLayer extends AbstractLayer<GPSSegment> { private RTree rtree; private final HashMap<Integer, GPSSegment> META_DATA = new HashMap<Integer, GPSSegment>(); public GPSSegmentLayer(String name, RenderingOptions renderingOptions) { super(name, renderingOptions); reset(); } public GPSSegmentLayer(String name, String description, RenderingOptions renderingOptions) { super(name, description, renderingOptions); reset(); } private void reset() { META_DATA.clear(); Properties p = new Properties(); p.setProperty("MinNodeEntries", "10"); p.setProperty("MaxNodeEntries", "50"); rtree = new RTree(); rtree.init(p); } @Override public void add(GPSSegment item) { super.add(item); //To change body of generated methods, choose Tools | Templates. if (!META_DATA.containsKey(item.hashCode())) { com.infomatiq.jsi.Rectangle boundingBox = getBoundingBox(item); rtree.add(boundingBox, item.hashCode()); META_DATA.put(item.hashCode(), item); } } @Override public void addAll(Collection<GPSSegment> items) { for (GPSSegment item : items) { add(item); } } @Override public void remove(GPSSegment item) { super.remove(item); if (META_DATA.containsKey(item.hashCode())) { com.infomatiq.jsi.Rectangle boundingBox = getBoundingBox(item); rtree.delete(boundingBox, item.hashCode()); } } @Override public void clearRenderObjects() { super.clearRenderObjects(); //To change body of generated methods, choose Tools | Templates. reset(); } @Override protected void drawDrawables(Graphics2D graphics, Rectangle rectangle) { MapViewer mapViewer = getLayerManager().getMapViewer(); Dimension size = mapViewer.getSize(); GeoPosition position = mapViewer.convertPointToGeoPosition(new Point2D.Double(0, 0)); GeoPosition position1 = mapViewer.convertPointToGeoPosition(new Point2D.Double(size.width, size.height)); com.infomatiq.jsi.Rectangle rectangle1 = new com.infomatiq.jsi.Rectangle((float) position.getLongitude(), (float) position.getLatitude(), (float) position1.getLongitude(), (float) position1.getLatitude()); rtree.intersects(rectangle1, new GPSSegmentSeachProcedure()); } private com.infomatiq.jsi.Rectangle getBoundingBox(GPSSegment segment) { Area area = new Area(); for (ILocation location : segment) { // the added shape must have at least a size > 0 area.add(new Area(new Rectangle2D.Double(location.getLon(), location.getLat(), 0.0000000001, 0.0000000001))); } Rectangle2D boundingBox = area.getBounds2D(); float minLong = (float) boundingBox.getMinX(); float maxLat = (float) boundingBox.getMinY(); float maxLong = (float) boundingBox.getMaxX(); float minLat = (float) boundingBox.getMaxY(); com.infomatiq.jsi.Rectangle rectangle = new com.infomatiq.jsi.Rectangle(minLong, maxLat, maxLong, minLat); return rectangle; } private class GPSSegmentSeachProcedure implements TIntProcedure { private final HashSet<GPSSegment> segments = new HashSet<GPSSegment>(100); public GPSSegmentSeachProcedure() { } @Override public boolean execute(int value) { GPSSegment segment = META_DATA.get(value); GPSPoint lastPoint = null; if (segment != null) { for (GPSPoint point : segment) { if (getLayerManager().getMapViewer().convertGeoPositionToPoint(new GeoPosition(point.getLat(), point.getLon())) != null) { if (lastPoint != null) { drawLine(lastPoint, point, getRenderingOptions()); } drawPoint(point, getRenderingOptions()); } lastPoint = point; } } return true; } public Collection<GPSSegment> getSegments() { return segments; } } }