// Created by plusminus on 6:15:04 PM - Mar 27, 2009 package org.androad.sys.ors.adt.ts; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.osmdroid.util.BoundingBoxE6; import org.osmdroid.util.GeoPoint; import org.osmdroid.views.overlay.OverlayItem; import org.androad.util.constants.Constants; import android.util.Log; import com.att.research.rtree.RTree; import com.att.research.spatialindex.IData; import com.att.research.spatialindex.INode; import com.att.research.spatialindex.ISpatialIndex; import com.att.research.spatialindex.IVisitor; import com.att.research.spatialindex.Point; import com.att.research.storagemanager.MemoryStorageManager; import com.att.research.storagemanager.PropertySet; /** * * @author Nicolas Gramlich * * @param <T> */ public class ListBackedSpatialIndexOrganizer<T extends OverlayItem> implements ISpatialDataOrganizer<T> { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== private boolean mIndexBuilt = false; private final ISpatialIndex mSpatialIndex; protected final List<T> mFeatureList = new ArrayList<T>(); // =========================================================== // Constructors // =========================================================== public ListBackedSpatialIndexOrganizer() { final MemoryStorageManager sm = new MemoryStorageManager(); final PropertySet ps = new PropertySet(); ps.setProperty("FillFactor", 0.7d); ps.setProperty("IndexCapacity", 20); ps.setProperty("LeafCapacity", 20); ps.setProperty("Dimension", 2); this.mSpatialIndex = new RTree(ps, sm); } public ListBackedSpatialIndexOrganizer(final List<T> pItems) { this(); addAll(pItems); } // =========================================================== // Getter & Setter // =========================================================== @Override public boolean isIndexBuilt() { return this.mIndexBuilt; } @Override public List<T> getItems() { return this.mFeatureList; } @Override public void add(final T pItem) { if(this.mIndexBuilt) { throw new IllegalStateException("Trying to add after index was built."); } if(pItem != null) { this.mFeatureList.add(pItem); } } @Override public void addAll(final Collection<T> pItems){ if(this.mIndexBuilt) { throw new IllegalStateException("Trying to add after index was built."); } if(pItems != null) { this.mFeatureList.addAll(pItems); } } // =========================================================== // Methods from SuperClass/Interfaces // =========================================================== @Override public void clearIndex(){ this.mIndexBuilt = false; this.mFeatureList.clear(); } @Override public void buildIndex(){ this.mIndexBuilt = true; final double[] coords = new double[2]; for(int i = 0; i < this.mFeatureList.size(); i++){ Log.d(Constants.DEBUGTAG, "Inserting: " + i); final T ti = this.mFeatureList.get(i); coords[0] = ti.getPoint().getLatitudeE6() / 1E6; coords[1] = ti.getPoint().getLongitudeE6() / 1E6; this.mSpatialIndex.insertData(null, new Point(coords), i); } } @Override public List<T> getClosest(final GeoPoint pGeoPoint, final int pCount){ if(!this.mIndexBuilt) { throw new IllegalStateException("Trying to query before index was built."); } final List<T> out = new ArrayList<T>(); final double[] pointCoords = new double[]{pGeoPoint.getLatitudeE6() / 1E6, pGeoPoint.getLongitudeE6() / 1E6}; this.mSpatialIndex.nearestNeighborQuery(pCount, new Point(pointCoords ), new IVisitor(){ @Override public void visitData(final IData d) { out.add(ListBackedSpatialIndexOrganizer.this.mFeatureList.get(d.getIdentifier())); } @Override public void visitNode(final INode n) { } }); return out; } @Override public List<T> getWithinBoundingBox(final BoundingBoxE6 boundingBoxE6, final int count) { throw new IllegalStateException("Wrong method!"); } @Override public GetMode getGetMode() { return GetMode.CLOSEST; } // =========================================================== // Methods // =========================================================== // =========================================================== // Inner and Anonymous Classes // =========================================================== }