Moving notes implemented.

This commit is contained in:
GaidamakUA 2016-05-16 20:13:09 +03:00
parent a7fd0a832c
commit ad03bd3390
4 changed files with 144 additions and 92 deletions

View file

@ -26,16 +26,16 @@ import java.util.Map.Entry;
/**
* Basic algorithms that are not in jdk
* Basic algorithms that are not in jdk
*/
public class Algorithms {
private static final int BUFFER_SIZE = 1024;
private static final Log log = PlatformUtil.getLog(Algorithms.class);
public static boolean isEmpty(String s){
return s == null || s.length() == 0;
}
public static boolean isBlank(String s){
return s == null || s.trim().length() == 0;
}
@ -62,8 +62,8 @@ public class Algorithms {
}
return def;
}
public static String getFileNameWithoutExtension(File f) {
String name = f.getName();
int i = name.indexOf('.');
@ -72,9 +72,13 @@ public class Algorithms {
}
return name;
}
public static String getFileExtension(File f) {
String name = f.getName();
int i = name.lastIndexOf(".");
return name.substring(i + 1);
}
public static File[] getSortedFilesVersions(File dir){
File[] listFiles = dir.listFiles();
if (listFiles != null) {
@ -89,7 +93,7 @@ public class Algorithms {
public int compare(File o1, File o2) {
return -simplifyFileName(o1.getName()).compareTo(simplifyFileName(o2.getName()));
}
public String simplifyFileName(String fn) {
String lc = fn.toLowerCase();
if (lc.indexOf(".") != -1) {
@ -112,14 +116,14 @@ public class Algorithms {
}
};
}
private static final char CHAR_TOSPLIT = 0x01;
public static Map<String, String> decodeMap(String s) {
if (isEmpty(s)) {
return Collections.emptyMap();
}
Map<String, String> names = new HashMap<String, String>();
Map<String, String> names = new HashMap<>();
String[] split = s.split(CHAR_TOSPLIT + "");
// last split is an empty string
for (int i = 1; i < split.length; i += 2) {
@ -127,7 +131,7 @@ public class Algorithms {
}
return names;
}
public static String encodeMap(Map<String, String> names) {
if (names != null) {
Iterator<Entry<String, String>> it = names.entrySet().iterator();
@ -142,7 +146,7 @@ public class Algorithms {
}
return "";
}
public static int findFirstNumberEndIndex(String value) {
int i = 0;
boolean valid = false;
@ -159,7 +163,7 @@ public class Algorithms {
return -1;
}
}
public static boolean isDigit(char charAt) {
return charAt >= '0' && charAt <= '9';
}
@ -182,7 +186,7 @@ public class Algorithms {
in.close();
return test == 0x504b0304;
}
private static final int readInt(InputStream in) throws IOException {
int ch1 = in.read();
int ch2 = in.read();
@ -192,7 +196,7 @@ public class Algorithms {
throw new EOFException();
return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
}
public static String capitalizeFirstLetterAndLowercase(String s) {
if (s != null && s.length() > 1) {
// not very efficient algorithm
@ -201,8 +205,8 @@ public class Algorithms {
return s;
}
}
public static boolean objectEquals(Object a, Object b){
if(a == null){
return b == null;
@ -210,8 +214,8 @@ public class Algorithms {
return a.equals(b);
}
}
/**
* Parse the color string, and return the corresponding color-int.
* If the string cannot be parsed, throws an IllegalArgumentException
@ -225,7 +229,7 @@ public class Algorithms {
if (colorString.charAt(0) == '#') {
// Use a long to avoid rollovers on #ffXXXXXX
if (colorString.length() == 4) {
colorString = "#" +
colorString = "#" +
colorString.charAt(1) + colorString.charAt(1) +
colorString.charAt(2) + colorString.charAt(2) +
colorString.charAt(3) + colorString.charAt(3);
@ -241,8 +245,8 @@ public class Algorithms {
}
throw new IllegalArgumentException("Unknown color " + colorString); //$NON-NLS-1$
}
public static int extractFirstIntegerNumber(String s) {
int i = 0;
for (int k = 0; k < s.length(); k++) {
@ -254,7 +258,7 @@ public class Algorithms {
}
return i;
}
public static int extractIntegerNumber(String s) {
int i = 0;
int k = 0;
@ -272,7 +276,7 @@ public class Algorithms {
}
return i;
}
public static String extractIntegerPrefix(String s) {
int k = 0;
for (; k < s.length(); k++) {
@ -282,7 +286,7 @@ public class Algorithms {
}
return "";
}
public static String extractOnlyIntegerSuffix(String s) {
int k = 0;
for (; k < s.length(); k++) {
@ -292,7 +296,7 @@ public class Algorithms {
}
return "";
}
public static String extractIntegerSuffix(String s) {
int k = 0;
for (; k < s.length(); k++) {
@ -302,8 +306,8 @@ public class Algorithms {
}
return "";
}
public static void fileCopy(File src, File dst) throws IOException {
FileOutputStream fout = new FileOutputStream(dst);
try {
@ -324,8 +328,8 @@ public class Algorithms {
out.write(b, 0, read);
}
}
public static void streamCopy(InputStream in, OutputStream out, IProgress pg, int bytesDivisor) throws IOException{
byte[] b = new byte[BUFFER_SIZE];
int read;
@ -335,18 +339,18 @@ public class Algorithms {
cp += read;
if(pg != null && cp > bytesDivisor) {
pg.progress(cp / bytesDivisor);
cp = cp % bytesDivisor;
cp = cp % bytesDivisor;
}
}
}
public static void oneByteStreamCopy(InputStream in, OutputStream out) throws IOException{
int read;
while ((read = in.read()) != -1) {
out.write(read);
}
}
public static void closeStream(Closeable stream){
try {
if(stream != null){
@ -356,7 +360,7 @@ public class Algorithms {
log.warn("Closing stream warn", e); //$NON-NLS-1$
}
}
public static void updateAllExistingImgTilesToOsmandFormat(File f){
if(f.isDirectory()){
for(File c : f.listFiles()){
@ -367,9 +371,9 @@ public class Algorithms {
} else if(f.getName().endsWith(".andnav2")) { //$NON-NLS-1$
f.renameTo(new File(f.getAbsolutePath().substring(0, f.getAbsolutePath().length() - ".andnav2".length()) + ".tile")); //$NON-NLS-1$ //$NON-NLS-2$
}
}
public static StringBuilder readFromInputStream(InputStream i) throws IOException {
StringBuilder responseBody = new StringBuilder();
responseBody.setLength(0);
@ -388,7 +392,7 @@ public class Algorithms {
}
return responseBody;
}
public static boolean removeAllFiles(File f) {
if (f == null) {
return false;
@ -405,8 +409,8 @@ public class Algorithms {
return f.delete();
}
}
public static long parseLongFromBytes(byte[] bytes, int offset) {
long o= 0xff & bytes[offset + 7];
o = o << 8 | (0xff & bytes[offset + 6]);
@ -418,9 +422,9 @@ public class Algorithms {
o = o << 8 | (0xff & bytes[offset]);
return o;
}
public static void putLongToBytes(byte[] bytes, int offset, long l){
bytes[offset] = (byte) (l & 0xff);
l >>= 8;
@ -438,8 +442,8 @@ public class Algorithms {
l >>= 8;
bytes[offset + 7] = (byte) (l & 0xff);
}
public static int parseIntFromBytes(byte[] bytes, int offset) {
int o = (0xff & bytes[offset + 3]) << 24;
o |= (0xff & bytes[offset + 2]) << 16;
@ -447,7 +451,7 @@ public class Algorithms {
o |= (0xff & bytes[offset]);
return o;
}
public static void putIntToBytes(byte[] bytes, int offset, int l){
bytes[offset] = (byte) (l & 0xff);
l >>= 8;
@ -457,8 +461,8 @@ public class Algorithms {
l >>= 8;
bytes[offset + 3] = (byte) (l & 0xff);
}
public static void writeLongInt(OutputStream stream, long l) throws IOException {
stream.write((int) (l & 0xff));
l >>= 8;
@ -476,7 +480,7 @@ public class Algorithms {
l >>= 8;
stream.write((int) (l & 0xff));
}
public static void writeInt(OutputStream stream, int l) throws IOException {
stream.write(l & 0xff);
l >>= 8;
@ -486,7 +490,7 @@ public class Algorithms {
l >>= 8;
stream.write(l & 0xff);
}
public static void writeSmallInt(OutputStream stream, int l) throws IOException {
stream.write(l & 0xff);
@ -494,13 +498,13 @@ public class Algorithms {
stream.write(l & 0xff);
l >>= 8;
}
public static int parseSmallIntFromBytes(byte[] bytes, int offset) {
int s = (0xff & bytes[offset + 1]) << 8;
s |= (0xff & bytes[offset]);
return s;
}
public static void putSmallIntBytes(byte[] bytes, int offset, int s){
bytes[offset] = (byte) (s & 0xff);
s >>= 8;
@ -516,7 +520,7 @@ public class Algorithms {
}
return false;
}
public static String formatDuration(int seconds, boolean fullForm) {
String sec;
@ -549,7 +553,7 @@ public class Algorithms {
return String.format("%02d:%02d", hours, min);
}
}
public static <T extends Enum<T> > T parseEnumValue(T[] cl, String val, T defaultValue){
for(int i = 0; i< cl.length; i++) {
if(cl[i].name().equalsIgnoreCase(val)) {

View file

@ -7,6 +7,9 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import net.osmand.data.DataTileManager;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
@ -16,6 +19,7 @@ import net.osmand.data.RotatedTileBox;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin.Recording;
import net.osmand.plus.views.ContextMenuLayer;
import net.osmand.plus.views.ContextMenuLayer.IContextMenuProvider;
import net.osmand.plus.views.OsmandMapLayer;
import net.osmand.plus.views.OsmandMapTileView;
@ -24,20 +28,22 @@ import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.List;
public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvider {
public class AudioNotesLayer extends OsmandMapLayer implements
IContextMenuProvider, ContextMenuLayer.IMoveObjectProvider {
private static final int startZoom = 10;
private MapActivity activity;
private AudioVideoNotesPlugin plugin;
private Paint pointAltUI;
private Paint paintIcon;
private Paint point;
private OsmandMapTileView view;
private Bitmap audio;
private Bitmap video;
private Bitmap photo;
private Bitmap pointSmall;
private ContextMenuLayer contextMenuLayer;
public AudioNotesLayer(MapActivity activity, AudioVideoNotesPlugin plugin) {
this.activity = activity;
this.plugin = plugin;
@ -50,7 +56,7 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
pointAltUI = new Paint();
pointAltUI.setColor(0xa0FF3344);
pointAltUI.setStyle(Style.FILL);
audio = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_note_audio);
video = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_note_video);
photo = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_note_photo);
@ -59,15 +65,17 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
paintIcon = new Paint();
point = new Paint();
Paint point = new Paint();
point.setColor(Color.GRAY);
point.setAntiAlias(true);
point.setStyle(Style.STROKE);
contextMenuLayer = view.getLayerByClass(ContextMenuLayer.class);
}
public int getRadiusPoi(RotatedTileBox tb){
public int getRadiusPoi(RotatedTileBox tb) {
int r = 0;
if(tb.getZoom() < startZoom){
if (tb.getZoom() < startZoom) {
r = 0;
} else {
r = 15;
@ -77,8 +85,13 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
@Override
public void onDraw(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (contextMenuLayer.getMoveableObject() instanceof Recording) {
Recording objectInMotion = (Recording) contextMenuLayer.getMoveableObject();
PointF pf = contextMenuLayer.getMoveableCenterPoint(tileBox);
drawRecording(canvas, objectInMotion, pf.x, pf.y);
}
}
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (tileBox.getZoom() >= startZoom) {
@ -92,35 +105,41 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
List<LatLon> fullObjectsLatLon = new ArrayList<>();
List<LatLon> smallObjectsLatLon = new ArrayList<>();
for (Recording o : objects) {
float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
if (o != contextMenuLayer.getMoveableObject()) {
float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
if (intersects(boundIntersections, x, y, iconSize, iconSize)) {
canvas.drawBitmap(pointSmall, x - pointSmall.getWidth() / 2, y - pointSmall.getHeight() / 2, paintIcon);
smallObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
} else {
fullObjects.add(o);
fullObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
if (intersects(boundIntersections, x, y, iconSize, iconSize)) {
canvas.drawBitmap(pointSmall, x - pointSmall.getWidth() / 2, y - pointSmall.getHeight() / 2, paintIcon);
smallObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
} else {
fullObjects.add(o);
fullObjectsLatLon.add(new LatLon(o.getLatitude(), o.getLongitude()));
}
}
}
for (Recording o : fullObjects) {
float x = tileBox.getPixXFromLatLon(o.getLatitude(), o.getLongitude());
float y = tileBox.getPixYFromLatLon(o.getLatitude(), o.getLongitude());
Bitmap b;
if (o.isPhoto()) {
b = photo;
} else if (o.isAudio()) {
b = audio;
} else {
b = video;
}
canvas.drawBitmap(b, x - b.getWidth() / 2, y - b.getHeight() / 2, paintIcon);
drawRecording(canvas, o, x, y);
}
this.fullObjectsLatLon = fullObjectsLatLon;
this.smallObjectsLatLon = smallObjectsLatLon;
}
}
private void drawRecording(Canvas canvas, Recording o, float x, float y) {
Bitmap b;
if (o.isPhoto()) {
b = photo;
} else if (o.isAudio()) {
b = audio;
} else {
b = video;
}
canvas.drawBitmap(b, x - b.getWidth() / 2, y - b.getHeight() / 2, paintIcon);
}
@Override
public void destroyLayer() {
}
@ -130,13 +149,13 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
return true;
}
@Override
public PointDescription getObjectName(Object o) {
if(o instanceof Recording){
if (o instanceof Recording) {
Recording rec = (Recording) o;
String recName = rec.getName(activity, true);
if(Algorithms.isEmpty(recName)) {
if (Algorithms.isEmpty(recName)) {
return new PointDescription(rec.getSearchHistoryType(), view.getResources().getString(R.string.recording_default_name));
}
return new PointDescription(rec.getSearchHistoryType(), recName);
@ -165,7 +184,7 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
getRecordingsFromPoint(point, tileBox, objects);
}
}
public void getRecordingsFromPoint(PointF point, RotatedTileBox tileBox, List<? super Recording> am) {
int ex = (int) point.x;
int ey = (int) point.y;
@ -182,17 +201,31 @@ public class AudioNotesLayer extends OsmandMapLayer implements IContextMenuProvi
}
private boolean calculateBelongs(int ex, int ey, int objx, int objy, int radius) {
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius ;
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius;
}
@Override
public LatLon getObjectLocation(Object o) {
if(o instanceof Recording){
return new LatLon(((Recording)o).getLatitude(), ((Recording)o).getLongitude());
if (o instanceof Recording) {
return new LatLon(((Recording) o).getLatitude(), ((Recording) o).getLongitude());
}
return null;
}
@Override
public boolean isObjectMovable(Object o) {
return o instanceof Recording;
}
@Override
public void applyNewObjectPosition(@NonNull Object o, @NonNull LatLon position, @Nullable ContextMenuLayer.ApplyMovedObjectCallback callback) {
boolean result = false;
if (o instanceof Recording) {
result = ((Recording) o).setLocation(position);
}
if (callback != null) {
callback.onApplyMovedObject(result, o);
}
}
}

View file

@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Build;
import android.os.StatFs;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.view.Display;
@ -254,6 +255,18 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
return false;
}
public boolean setLocation(LatLon latLon) {
File directory = file.getParentFile();
lat = latLon.getLatitude();
lon = latLon.getLongitude();
File to = getBaseFileName(lat, lon, directory, Algorithms.getFileExtension(file));
if (file.renameTo(to)) {
file = to;
return true;
}
return false;
}
public String getFileName() {
return file.getName();
}
@ -764,14 +777,18 @@ public class AudioVideoNotesPlugin extends OsmandPlugin {
}
}
private File getBaseFileName(double lat, double lon, OsmandApplication app, String ext) {
private static File getBaseFileName(double lat, double lon, OsmandApplication app, String ext) {
File baseDir = app.getAppPath(IndexConstants.AV_INDEX_DIR);
return getBaseFileName(lat, lon, baseDir, ext);
}
private static File getBaseFileName(double lat, double lon, @NonNull File baseDir, @NonNull String ext) {
String basename = MapUtils.createShortLinkString(lat, lon, 15);
int k = 1;
File f = app.getAppPath(IndexConstants.AV_INDEX_DIR);
f.mkdirs();
baseDir.mkdirs();
File fl;
do {
fl = new File(f, basename + "." + (k++) + "." + ext);
fl = new File(baseDir, basename + "." + (k++) + "." + ext);
} while (fl.exists());
return fl;
}

View file

@ -45,8 +45,6 @@ public class FavoritesLayer extends OsmandMapLayer implements ContextMenuLayer.
private int defaultColor;
private OsmandSettings settings;
protected String getObjName() {
return view.getContext().getString(R.string.favorite);