www.pudn.com > GMapViewer-src.zip > MapPinManager.java
package org.sreid.j2me.gmapviewer;
import java.util.*;
import javax.microedition.rms.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import org.sreid.j2me.util.*;
// Handles permanent map pins, and temporary search result map pins.
class MapPinManager {
private static final String RECORD_STORE_NAME = "GMapViewer.mappins";
private final GMapViewer app;
private RecordStore rms;
private final Vector mapPins = new Vector();
MapPinManager(GMapViewer app) {
this.app = app;
}
void openRMS() {
try {
rms = RecordStore.openRecordStore(RECORD_STORE_NAME, true);
RecordEnumeration re = rms.enumerateRecords(null, null, false);
mapPins.removeAllElements();
byte[] buffer = new byte[500];
while (re.hasNextElement()) {
int id = re.nextRecordId();
try {
int rlen = rms.getRecord(id, buffer, 0);
MapPin mp = new MapPin(buffer, 0, rlen);
mp.rmsID = id;
mapPins.addElement(mp);
}
catch (Exception e) {
app.exception("An error occured while reading a map pin from RMS.", e);
rms.deleteRecord(id);
}
}
}
catch (Exception e) {
app.exception("An error occured while enumerating map pin RMS.", e);
}
}
void closeRMS() {
try {
rms.closeRecordStore();
}
catch (Exception e) {
app.exception("An error occured while closing map pin RMS.", e);
}
}
/** Call this whenever a pin changes. */
void keepPin(MapPin pin) {
if (!mapPins.contains(pin)) {
mapPins.addElement(pin);
sortPinsNearestFirst();
}
if (pin.isPermanent) {
try {
byte[] buffer = new byte[500];
int rlen = pin.toBytes(buffer, 0);
if (pin.rmsID == -1) {
pin.rmsID = rms.addRecord(buffer, 0, rlen);
}
else {
rms.setRecord(pin.rmsID, buffer, 0, rlen);
}
}
catch (Exception e) {
app.exception("An error occured while saving a map pin to RMS.", e);
}
}
}
void deletePin(MapPin pin) {
mapPins.removeElement(pin);
if (pin.rmsID != -1) {
try {
rms.deleteRecord(pin.rmsID);
}
catch (Exception e) {
app.exception("An error occured while deleting a map pin from RMS.", e);
}
finally {
pin.rmsID = -1;
}
}
}
void deleteNonPermanentPins() {
for (int i = mapPins.size() - 1; i >= 0; i--) {
if (!getMapPin(i).isPermanent) mapPins.removeElementAt(i);
}
}
void sortPinsNearestFirst() {
final int x = app.canvas.getX();
final int y = app.canvas.getY();
// Copy to temporary array
Object[] array = new Object[mapPins.size()];
mapPins.copyInto(array);
// Sort temporary array
Sort.sort(array, new Comparator() {
public int compare(Object o1, Object o2) {
MapPin p1 = (MapPin)o1;
MapPin p2 = (MapPin)o2;
if (p1.isPermanent && p2.isPermanent) {
// Sort permanent pins by distance from current position.
// Pythagorean theorem. Using longs here because distance^2 may be large.
long xd1 = Math.abs(p1.x - x);
long yd1 = Math.abs(p1.y - y);
long d1 = (xd1 * xd1) + (yd1 * yd1);
long xd2 = Math.abs(p2.x - x);
long yd2 = Math.abs(p2.y - y);
long d2 = (xd2 * xd2) + (yd2 * yd2);
if (d1 < d2) return -1;
if (d1 > d2) return 1;
return 0;
}
else {
// Search pins should not have their order changed.
if (p1.isPermanent && !p2.isPermanent) return 1;
if (!p1.isPermanent && p2.isPermanent) return -1;
return 0; // both non-permanent, preserve order (requires a stable sort)
}
}
});
// Copy back to Vector
for (int i = 0; i < array.length; i++) {
mapPins.setElementAt(array[i], i);
}
}
Enumeration enumeration() {
return mapPins.elements();
}
MapPin getMapPin(int index) {
return (MapPin)mapPins.elementAt(index);
}
int getMapPinCount() {
return mapPins.size();
}
}