diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryMapDataObject.java b/OsmAnd-java/src/net/osmand/binary/BinaryMapDataObject.java index d070cdbfd2..f6a2fe2640 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryMapDataObject.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryMapDataObject.java @@ -6,7 +6,6 @@ import gnu.trove.map.hash.TIntObjectHashMap; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.Map; -import java.util.TreeSet; import net.osmand.binary.BinaryMapIndexReader.MapIndex; import net.osmand.binary.BinaryMapIndexReader.TagValuePair; diff --git a/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java b/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java index 0086ed7950..1c87fef158 100644 --- a/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/OsmAnd-java/src/net/osmand/binary/BinaryMapIndexReader.java @@ -1742,6 +1742,7 @@ public class BinaryMapIndexReader { } return null; } + public LatLon getCenterLatLon() { if(roots.size() == 0) { @@ -1760,6 +1761,14 @@ public class BinaryMapIndexReader { public TagValuePair decodeType(int type) { return decodingRules.get(type); } + + public Integer getRule(TagValuePair tv) { + Map m = encodingRules.get(tv.tag); + if (m != null) { + return m.get(tv.value); + } + return null; + } public void finishInitializingTags() { int free = decodingRules.size(); @@ -1824,6 +1833,69 @@ public class BinaryMapIndexReader { public int getFieldNumber() { return OsmandOdb.OsmAndStructure.MAPINDEX_FIELD_NUMBER; } + + public BinaryMapDataObject adoptMapObject(BinaryMapDataObject o) { + if(o.mapIndex == this) { + return o; + } + if(encodingRules.isEmpty()) { + encodingRules.putAll(o.mapIndex.encodingRules); + decodingRules.putAll(o.mapIndex.decodingRules); + return o; + } + TIntArrayList types = new TIntArrayList(); + TIntArrayList additionalTypes = new TIntArrayList(); + if (o.types != null) { + for (int i = 0; i < o.types.length; i++) { + TagValuePair tp = o.mapIndex.decodeType(o.types[i]); + Integer r = getRule(tp); + if(r != null) { + types.add(r); + } else { + int nid = decodingRules.size(); + initMapEncodingRule(tp.additionalAttribute, decodingRules.size(), tp.tag, tp.value); + types.add(nid); + } + } + } + if (o.additionalTypes != null) { + for (int i = 0; i < o.additionalTypes.length; i++) { + TagValuePair tp = o.mapIndex.decodeType(o.additionalTypes[i]); + Integer r = getRule(tp); + if(r != null) { + additionalTypes.add(r); + } else { + int nid = decodingRules.size(); + initMapEncodingRule(tp.additionalAttribute, decodingRules.size(), tp.tag, tp.value); + additionalTypes.add(nid); + } + } + } + + BinaryMapDataObject bm = + new BinaryMapDataObject(o.id, o.coordinates, o.polygonInnerCoordinates, o.objectType, o.area, + types.toArray(), additionalTypes.isEmpty() ? null : additionalTypes.toArray()); + if (o.namesOrder != null) { + bm.objectNames = new TIntObjectHashMap<>(); + bm.namesOrder = new TIntArrayList(); + for (int i = 0; i < o.namesOrder.size(); i++) { + int nameType = o.namesOrder.get(i); + String name = o.objectNames.get(nameType); + TagValuePair tp = o.mapIndex.decodeType(nameType); + Integer r = getRule(tp); + if(r != null) { + bm.namesOrder.add(r); + bm.objectNames.put(r, name); + } else { + int nid = decodingRules.size(); + initMapEncodingRule(tp.additionalAttribute, decodingRules.size(), tp.tag, tp.value); + additionalTypes.add(nid); + bm.objectNames.put(nid, name); + } + } + } + return bm; + } } public static class TagValuePair { @@ -1906,6 +1978,11 @@ public class BinaryMapIndexReader { } private List trees = null; + + + public MapZooms.MapZoomPair getMapZoom() { + return new MapZooms.MapZoomPair(minZoom, maxZoom); + } } private static class MapTree { diff --git a/OsmAnd-java/src/net/osmand/binary/MapZooms.java b/OsmAnd-java/src/net/osmand/binary/MapZooms.java new file mode 100644 index 0000000000..faaade2457 --- /dev/null +++ b/OsmAnd-java/src/net/osmand/binary/MapZooms.java @@ -0,0 +1,137 @@ +package net.osmand.binary; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class MapZooms { + + public static class MapZoomPair { + public static int MAX_ALLOWED_ZOOM = 22; + private int minZoom; + private int maxZoom; + + public MapZoomPair(int minZoom, int maxZoom) { + this.maxZoom = maxZoom; + this.minZoom = minZoom; + } + + public int getMinZoom() { + return minZoom; + } + + public int getMaxZoom() { + return maxZoom; + } + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + maxZoom; + result = prime * result + minZoom; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MapZoomPair other = (MapZoomPair) obj; + if (maxZoom != other.maxZoom) + return false; + if (minZoom != other.minZoom) + return false; + return true; + } + + @Override + public String toString() { + return "MapZoomPair : " + minZoom + " - "+ maxZoom; + } + } + + private List levels = new ArrayList(); + private boolean simplify; + + + public List getLevels() { + return levels; + } + + public void setLevels(List levels) { + this.levels = levels; + Collections.sort(levels, new Comparator() { + + @Override + public int compare(MapZoomPair o1, MapZoomPair o2) { + return -new Integer(o1.getMaxZoom()).compareTo(o2.getMaxZoom()); + } + }); + } + /** + * @param zooms - could be 5-8;7-10;11-14;15- + */ + public static MapZooms parseZooms(String zooms) throws IllegalArgumentException { + String[] split = zooms.split(";"); + + + int zeroLevel = 15; + List list = new ArrayList(); + for(String s : split){ + s = s.trim(); + if(s.length() == 0) { + continue; + } + int i = s.indexOf('-'); + if (i == -1) { + zeroLevel = Integer.parseInt(s); + list.add(0, new MapZoomPair(zeroLevel, zeroLevel)); + } else if(s.endsWith("-")){ + list.add(0, new MapZoomPair(Integer.parseInt(s.substring(0, i)), MapZoomPair.MAX_ALLOWED_ZOOM)); + } else { + list.add(0, new MapZoomPair(Integer.parseInt(s.substring(0, i)), Integer.parseInt(s.substring(i + 1)))); + } + } + if(list.size() < 1 || list.size() > 8){ + throw new IllegalArgumentException("Map zooms should have at least 1 level and less than 8 levels"); + } + MapZooms mapZooms = new MapZooms(); + mapZooms.setSimplify(zooms.endsWith(";")); + mapZooms.setLevels(list); + return mapZooms; + } + + private void setSimplify(boolean simplify) { + this.simplify = simplify; + } + + public boolean isDetailedZoomSimplified() { + return simplify; + } + + public int size(){ + return levels.size(); + } + + public MapZoomPair getLevel(int level){ + return levels.get(level); + } + + private static MapZooms DEFAULT = null; + public static String MAP_ZOOMS_DEFAULT = "11;12;13-14;15-"; + public static MapZooms getDefault(){ + if(DEFAULT == null){ + DEFAULT = parseZooms(MAP_ZOOMS_DEFAULT); + } + return DEFAULT; + + } + +} diff --git a/OsmAnd/res/layout/close_measurement_tool_dialog.xml b/OsmAnd/res/layout/close_measurement_tool_dialog.xml new file mode 100644 index 0000000000..6485e8582f --- /dev/null +++ b/OsmAnd/res/layout/close_measurement_tool_dialog.xml @@ -0,0 +1,22 @@ + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values-da/strings.xml b/OsmAnd/res/values-da/strings.xml index 42845c9a1e..108e3cb495 100644 --- a/OsmAnd/res/values-da/strings.xml +++ b/OsmAnd/res/values-da/strings.xml @@ -2844,7 +2844,7 @@ Tidligere destination bliver sidste mellemliggende punkt. Tilføj punkt før Tilføj punkt efter Indstillinger - OsmAnd vil tilføje yderligere punkter, tilpasset typen af navigation. + Tilføjer yderligere punkter, tilpasset typen af navigation. Gem punkterne enten som rutepunkter eller som en linje. Vælg navigationstype Tilføj rutepunkter diff --git a/OsmAnd/res/values-it/strings.xml b/OsmAnd/res/values-it/strings.xml index 814416d5f1..512c73f1fc 100644 --- a/OsmAnd/res/values-it/strings.xml +++ b/OsmAnd/res/values-it/strings.xml @@ -2620,28 +2620,28 @@ Rappresenta l\'area: %1$s x %2$s La sorgente della mappa è stata cambiata in \"%s\". Cambia la posizione del pulsante Tieni premuto e trascina per cambiare la sua posizione nello schermo - Linee isoipse marine + Isoipse nautiche Divisione automatica delle registrazioni dopo un periodo Inizia un nuovo segmento dopo 6 minuti, una nuova traccia dopo 2 ore, o un nuovo file dopo un intervallo maggiore. Mostra contorni e punti in profondità - "\\u2022 Nuove funzionalità: Pulsante azione veloce -\n + "• Nuove funzionalità: Pulsante azione veloce +\n \n • Migliorata la risposta del touch screen ai gesti (es. zoommare e allargare) \n \n • Nuovi caratteri della mappa mappa per estendere la copertura di più lingue -\n +\n \n • Supporto TTS per le lingue locali (e accenti) -\n +\n \n • Miglioramento della visibilità in molti stili mappa e wikipedia -\n +\n \n • Supporto all\'Open Location Code (OLC) -\n +\n \n • Visualizzazione di un profilo altimetrico, pendenza, e velocità per i GPX registrati e percorsi calcolati -\n +\n \n • Impostazione e miglioramenti della logica dello \"Stile guida\" nella guida svolta per svolta in bicicletta -\n +\n \n • Molti altri miglioramenti e correzioni di errori -\n +\n \n e altro ancora…" Stile di guida @@ -2654,7 +2654,7 @@ Rappresenta l\'area: %1$s x %2$s Distanza totale Più piatto o più colline - Utilizza dati elevazione + Utilizza dati di quota Utilizza i dati di elevazione del terreno forniti da SRTM, ASTER e EU-DEM Intervallo di tempo @@ -2858,7 +2858,7 @@ Copertura e qualità approssimativamente: \n \n • Widget righello per la misurazione della distanza \n -\n • Informazioni dettagliate e suddivisore delle tue tracce GPX +\n • Scelta degli intervalli delle tracce GPX con informazioni dettagliate sul tuo percorso \n \n • Altre migliorie e correzioni di errori \n @@ -2882,7 +2882,7 @@ Copertura e qualità approssimativamente: Aggiungi un punto prima Aggiungi un punto dopo Opzioni - OsmAnd aggiugerà dei punti, in base al tipo di navigazione. + OsmAnd aggiungerà dei punti, in base al tipo di navigazione. Puoi salvare i punti sia come punti di un percorso che come linea. Scegli la modalità di navigazione diff --git a/OsmAnd/res/values-pl/phrases.xml b/OsmAnd/res/values-pl/phrases.xml index 1c9c0abb62..d5295f4e74 100644 --- a/OsmAnd/res/values-pl/phrases.xml +++ b/OsmAnd/res/values-pl/phrases.xml @@ -3479,4 +3479,29 @@ Kierunek: dół Pokój zimowy: tak Pokój zimowy: nie - + Wypożyczane łodzie + +Uwalnianie: tak + Uwalnianie: nie + + Kosmodrom + + Wypożyczalnia łodzi + Motorówki: tak + Motorówki: nie + Barki mieszkalne: tak + Barki mieszkalne: nie + Rowery wodne: tak + Rowery wodne: nie + Skutery wodne: tak + Skutery wodne: nie + Żaglówki: tak + Żaglówki: nie + Łodzie wiosłowe: tak + Łodzie wiosłowe: nie + Kajaki: tak + Kajaki: nie + Kanadyjki: tak + Kanadyjki: nie + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 29df34dfbd..352d6b9ce4 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -9,6 +9,8 @@ 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy --> + Keep showing on map + Exit without saving? Line Save as route points Save as line diff --git a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java index 9072e36b17..2cda80c018 100644 --- a/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java +++ b/OsmAnd/src/net/osmand/plus/measurementtool/MeasurementToolFragment.java @@ -464,16 +464,9 @@ public class MeasurementToolFragment extends Fragment { if (pointsListOpened) { hidePointsList(); } - if (editingCtx.getOriginalPointToMove() != null) { - switchMovePointMode(false); - } else if (editingCtx.getSelectedPointPosition() != -1) { - switchAddPointBeforeAfterMode(false); - } + closeModes(); MeasurementToolLayer layer = getMeasurementLayer(); if (layer != null) { - if (editingCtx.getOriginalPointToMove() != null) { - layer.exitMovePointMode(true); - } layer.setOnSingleTapListener(null); layer.setOnEnterMovePointModeListener(null); } @@ -859,6 +852,18 @@ public class MeasurementToolFragment extends Fragment { } } + private void closeModes() { + if (editingCtx.getOriginalPointToMove() != null) { + switchMovePointMode(false); + } else if (editingCtx.getSelectedPointPosition() != -1) { + switchAddPointBeforeAfterMode(false); + } + MeasurementToolLayer layer = getMeasurementLayer(); + if (layer != null && editingCtx.getOriginalPointToMove() != null) { + layer.exitMovePointMode(true); + } + } + private void addPointBeforeAfter() { MeasurementToolLayer measurementLayer = getMeasurementLayer(); if (measurementLayer != null) { @@ -1119,7 +1124,7 @@ public class MeasurementToolFragment extends Fragment { fout = new File(dir, fileName); } } - saveNewGpx(dir, fileName, showOnMapToggle.isChecked(), saveType); + saveNewGpx(dir, fileName, showOnMapToggle.isChecked(), saveType, false); } }) .setNegativeButton(R.string.shared_string_cancel, null) @@ -1127,12 +1132,12 @@ public class MeasurementToolFragment extends Fragment { } } - private void saveNewGpx(File dir, String fileName, boolean checked, SaveType saveType) { - saveGpx(dir, fileName, checked, null, false, null, saveType); + private void saveNewGpx(File dir, String fileName, boolean checked, SaveType saveType, boolean close) { + saveGpx(dir, fileName, checked, null, false, null, saveType, close); } private void saveExistingGpx(GPXFile gpx, boolean showOnMap, NewGpxData.ActionType actionType, boolean openTrackActivity) { - saveGpx(null, null, showOnMap, gpx, openTrackActivity, actionType, null); + saveGpx(null, null, showOnMap, gpx, openTrackActivity, actionType, null, false); } private void saveGpx(final File dir, @@ -1141,7 +1146,8 @@ public class MeasurementToolFragment extends Fragment { final GPXFile gpx, final boolean openTrackActivity, final NewGpxData.ActionType actionType, - final SaveType saveType) { + final SaveType saveType, + final boolean close) { new AsyncTask() { @@ -1150,6 +1156,7 @@ public class MeasurementToolFragment extends Fragment { @Override protected void onPreExecute() { + closeModes(); MapActivity activity = getMapActivity(); if (activity != null) { progressDialog = new ProgressDialog(activity); @@ -1241,6 +1248,9 @@ public class MeasurementToolFragment extends Fragment { Toast.makeText(activity, MessageFormat.format(getString(R.string.gpx_saved_sucessfully), toSave.getAbsolutePath()), Toast.LENGTH_LONG).show(); + if (close) { + dismiss(activity); + } } } else { Toast.makeText(activity, warning, Toast.LENGTH_LONG).show(); @@ -1369,17 +1379,49 @@ public class MeasurementToolFragment extends Fragment { dismiss(mapActivity); return; } - new AlertDialog.Builder(mapActivity) - .setTitle(getString(R.string.are_you_sure)) + AlertDialog.Builder builder = new AlertDialog.Builder(mapActivity); + if (editingCtx.getNewGpxData() == null) { + final File dir = mapActivity.getMyApplication().getAppPath(IndexConstants.GPX_INDEX_DIR); + final LayoutInflater inflater = mapActivity.getLayoutInflater(); + final View view = inflater.inflate(R.layout.close_measurement_tool_dialog, null); + final SwitchCompat showOnMapToggle = (SwitchCompat) view.findViewById(R.id.toggle_show_on_map); + + builder.setView(view); + builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final String name = new SimpleDateFormat("yyyy-M-dd_HH-mm_EEE", Locale.US).format(new Date()); + String fileName = name + GPX_SUFFIX; + File fout = new File(dir, fileName); + int ind = 1; + while (fout.exists()) { + fileName = name + "_" + (++ind) + GPX_SUFFIX; + fout = new File(dir, fileName); + } + saveNewGpx(dir, fileName, showOnMapToggle.isChecked(), SaveType.LINE, true); + } + }); + } else { + builder.setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + GPXFile gpx = editingCtx.getNewGpxData().getGpxFile(); + SelectedGpxFile selectedGpxFile = mapActivity.getMyApplication().getSelectedGpxHelper().getSelectedFileByPath(gpx.path); + boolean showOnMap = selectedGpxFile != null; + ActionType actionType = editingCtx.getNewGpxData().getActionType(); + saveExistingGpx(gpx, showOnMap, actionType, true); + } + }); + } + builder.setTitle(getString(R.string.exit_without_saving)) .setMessage(getString(R.string.unsaved_changes_will_be_lost)) - .setPositiveButton(R.string.shared_string_ok, new DialogInterface.OnClickListener() { + .setNegativeButton(R.string.shared_string_cancel, new DialogInterface.OnClickListener() { @Override - public void onClick(DialogInterface dialog, int which) { + public void onClick(DialogInterface dialogInterface, int i) { dismiss(mapActivity); } - }) - .setNegativeButton(R.string.shared_string_cancel, null) - .show(); + }); + builder.show(); } } diff --git a/README.md b/README.md index 2e64fb03dc..859ab4203f 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,6 @@ You are welcome to discuss any question regarding the project at the Google grou Get it on Google Play Get it on Amazon - -Get it on F-Droid Get it on AppStore