Merge pull request #10153 from osmandapp/master

update test branch
This commit is contained in:
Hardy 2020-11-09 09:06:10 +01:00 committed by GitHub
commit f931eb6389
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 181 additions and 17 deletions

158
GPX.md Normal file
View file

@ -0,0 +1,158 @@
The OsmAnd's GPX file format conforms to GPX 1.1 specification with additional data written as extensions. There are few sections of such data:
## Track appearance
These parameters are used to customize the appearance of a track on the map. Used inside "gpx" tag and applies to all tracks inside gpx.
#### Parameters
* **show_arrows** [*true, false*] - show / hide arrows along the path line.
* **width** [*thin, medium, bold, 1-24*] - width of a track line on the map. The thin, medium and bold are style depended values (should be defined as currentTrackWidth attribute).
* **color** [*#AARRGGBB, #RRGGBB*] - color of a track line on the map. Hex values.
* **split_type** [*no_split, distance, time*] - split type for a track.
* **split_interval** [*double*] - split interval for a track. Distance (meters), time (seconds).
#### Example:
```xml
<gpx version="1.1" creator="OsmAndRouterV2" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
...
<extensions>
<show_arrows>true</show_arrows>
<color>#4e4eff</color>
<split_type>distance</split_type>
<split_interval>2000.0</split_interval>
<width>bold</width>
</extensions>
</gpx>
```
## Details of a track point (trkpt)
Written to a gpx file while recording a track.
* **speed** (meters per second)
* **heading** (0-359 degrees)
#### Example:
```xml
<trkpt lat="52.397799" lon="4.575998">
<ele>203</ele>
<time>2019-05-08T10:36:43Z</time>
<hdop>3</hdop>
<extensions>
<heading>273</heading>
<speed>5.02</speed>
</extensions>
</trkpt>
```
## Calculated route(s)
This data contains information about a route built with **OsmAnd** (route segments, turns, road names and types, restrictions, etc.). With their help, route can be restored completely as if it had just been built even without the currently installed offline maps.
There can be several routes in one gpx file. Each of them is contained in a specific segment (**trkseg** / **extensions**). In this form, a gpx file is saved when exporting a constructed route or when saving a track that consists of several separate segments via the **Plan route**.
When using the **Plan route** tool, route key points (**rtept**) are additionally written to the gpx file. There can also be several **rte** blocks (according to a number of separate segments / tracks in a gpx file).
#### Gpx structure:
```xml
<trk>
<trkseg>
<!-- List of segment points. The order of the points corresponds to the order and length of the route segments (<route><segment length="x" ... />). -->
<!-- The value of the "length" attribute corresponds to the number of points in this segment of the route. -->
<trkpt ... ></trkpt>
<extensions>
<!-- List of route segments -->
<route>
<segment ... />
</route>
<!-- Properties of segments included in the route. -->
<!-- This data is taken from offline maps during the initial construction of a route. -->
<types>
<type ... />
</types>
</extensions>
</trkseg>
</trk>
<!-- List of intermediate route points. If there are multiple routes, the order of the rte list matches the order of the route segments. -->
<rte>
<rtept ... />
<!-- For routes built with the "Plan route", the parameters of key points are saved. -->
<extensions>
<!-- Route profile type for next segment (car, bicycle, pedestrian, etc.). -->
<profile>...</profile>
<!-- The index of the point in the gpx segment that corresponds to the first point of the calculated route for this segment. -->
<trkpt_idx>...</trkpt_idx>
</extensions>
</rtept>
</rte>
```
#### Example:
```xml
<gpx version="1.1" creator="OsmAndRouterV2" xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
<metadata>
<name>Fri 06 Nov 2020</name>
</metadata>
<trk>
<name>Fri 06 Nov 2020</name>
<trkseg>
<trkpt lat="52.3639849" lon="4.8900533">
<ele>0.801</ele>
</trkpt>
<trkpt lat="52.3636917" lon="4.8922849">
<ele>0.998</ele>
</trkpt>
<trkpt lat="52.3636885" lon="4.892309">
<ele>1</ele>
</trkpt>
<trkpt lat="52.3636426" lon="4.8922902">
<ele>0.963</ele>
</trkpt>
<trkpt lat="52.363564" lon="4.8922607">
<ele>0.899</ele>
</trkpt>
....
<extensions>
<route>
<segment id="7372058" length="3" segmentTime="178.44" speed="1.11" turnType="C" types="0,1,2,3,4,5,6" names="57" />
<segment id="334164679" length="5" segmentTime="86.11" speed="1.11" turnType="TR" turnAngle="91.88" types="7,8,0,9,10,11,12,13,6" pointTypes=";;14,15;16,17,18;" names="58" />
<segment id="334603581" length="6" segmentTime="75.5" speed="1.11" types="19,20,21,7,8,0,22,9,10,11,12,13,23,6" pointTypes=";14;16,24;16,24;14;" names="58" />
<segment id="446707354" length="3" segmentTime="8.32" speed="1.11" turnType="TSLL" turnAngle="-25.44" types="19,25,21,7,8,22,9,1,11,12,13,6" names="58" />
...
</route>
<types>
<type t="lit" v="yes" />
<type t="oneway" v="yes" />
<type t="highway" v="unclassified" />
<type t="surface" v="paving_stones" />
<type t="maxspeed" v="30" />
...
</types>
</extensions>
</trkseg>
</trk>
<rte>
<rtept lat="52.3639945" lon="4.8900532">
<extensions>
<profile>pedestrian</profile>
<trkpt_idx>0</trkpt_idx>
</extensions>
</rtept>
<rtept lat="52.3612797" lon="4.8911677">
<extensions>
<profile>pedestrian</profile>
<trkpt_idx>24</trkpt_idx>
</extensions>
</rtept>
<rtept lat="52.356996" lon="4.8912071">
<extensions>
<profile>pedestrian</profile>
<trkpt_idx>89</trkpt_idx>
</extensions>
</rtept>
<rtept lat="52.3542374" lon="4.8947024">
<extensions>
<profile>pedestrian</profile>
<trkpt_idx>121</trkpt_idx>
</extensions>
</rtept>
</rte>
</gpx>
```

View file

@ -13,6 +13,7 @@ import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect;
import net.osmand.data.QuadTree;
import net.osmand.data.RotatedTileBox;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.audionotes.AudioVideoNotesPlugin.Recording;
@ -69,8 +70,9 @@ public class AudioNotesLayer extends OsmandMapLayer implements
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
if (tileBox.getZoom() >= startZoom) {
float textScale = activity.getMyApplication().getSettings().TEXT_SCALE.get();
float iconSize = getIconSize(activity) * 3 / 2.5f * textScale;
OsmandApplication app = activity.getMyApplication();
float textScale = app.getSettings().TEXT_SCALE.get();
float iconSize = getIconSize(app);
QuadTree<QuadRect> boundIntersections = initBoundIntersections(tileBox);
DataTileManager<Recording> recs = plugin.getRecordings();

View file

@ -104,20 +104,21 @@ public class OsmBugsLayer extends OsmandMapLayer implements IContextMenuProvider
@Override
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) {
startZoom = activity.getMyApplication().getSettings().SHOW_OSM_BUGS_MIN_ZOOM.get();
OsmandApplication app = activity.getMyApplication();
startZoom = app.getSettings().SHOW_OSM_BUGS_MIN_ZOOM.get();
if (tileBox.getZoom() >= startZoom) {
// request to load
data.queryNewData(tileBox);
List<OpenStreetNote> objects = data.getResults();
if (objects != null) {
float textScale = activity.getMyApplication().getSettings().TEXT_SCALE.get();
float iconSize = getIconSize(activity) * 3 / 2.5f * textScale;
float textScale = app.getSettings().TEXT_SCALE.get();
float iconSize = getIconSize(app);
QuadTree<QuadRect> boundIntersections = initBoundIntersections(tileBox);
List<OpenStreetNote> fullObjects = new ArrayList<>();
List<LatLon> fullObjectsLatLon = new ArrayList<>();
List<LatLon> smallObjectsLatLon = new ArrayList<>();
boolean showClosed = activity.getMyApplication().getSettings().SHOW_CLOSED_OSM_BUGS.get();
boolean showClosed = app.getSettings().SHOW_CLOSED_OSM_BUGS.get();
for (OpenStreetNote o : objects) {
if (!o.isOpened() && !showClosed) {
continue;

View file

@ -1,6 +1,5 @@
package net.osmand.plus.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@ -44,6 +43,7 @@ import java.util.Map;
public abstract class OsmandMapLayer {
public static final float ICON_VISIBLE_PART_RATIO = 0.45f;
protected List<LatLon> fullObjectsLatLon;
protected List<LatLon> smallObjectsLatLon;
@ -235,8 +235,8 @@ public abstract class OsmandMapLayer {
return (int) (r * tb.getDensity());
}
protected int getIconSize(Context ctx) {
return ctx.getResources().getDimensionPixelSize(R.dimen.favorites_icon_outline_size);
protected float getIconSize(OsmandApplication app) {
return app.getResources().getDimensionPixelSize(R.dimen.favorites_icon_outline_size) * ICON_VISIBLE_PART_RATIO * app.getSettings().TEXT_SCALE.get();
}
public Rect getIconDestinationRect(float x, float y, int width, int height, float scale) {

View file

@ -95,7 +95,7 @@ public class FavouritesLayer extends OsmandMapLayer implements ContextMenuLayer.
if (this.settings.SHOW_FAVORITES.get() && favorites.isFavoritesLoaded()) {
if (tileBox.getZoom() >= startZoom) {
float textScale = this.settings.TEXT_SCALE.get();
float iconSize = getIconSize(view.getContext()) * 3 / 2.5f * textScale;
float iconSize = getIconSize(view.getApplication());
QuadTree<QuadRect> boundIntersections = initBoundIntersections(tileBox);
// request to load

View file

@ -494,7 +494,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
private void drawSelectedFilesPoints(Canvas canvas, RotatedTileBox tileBox, List<SelectedGpxFile> selectedGPXFiles) {
if (tileBox.getZoom() >= START_ZOOM) {
float textScale = view.getSettings().TEXT_SCALE.get();
float iconSize = getIconSize(view.getContext()) * 3 / 2.5f * textScale;
float iconSize = getIconSize(view.getApplication());
QuadTree<QuadRect> boundIntersections = initBoundIntersections(tileBox);
List<LatLon> fullObjectsLatLon = new ArrayList<>();

View file

@ -200,7 +200,7 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
objects = data.getResults();
if (objects != null) {
float textScale = app.getSettings().TEXT_SCALE.get();
float iconSize = getIconSize(app) * 1.5f * textScale;
float iconSize = getIconSize(app);
QuadTree<QuadRect> boundIntersections = initBoundIntersections(tileBox);
WaypointHelper wph = app.getWaypointHelper();
PointImageDrawable pointImageDrawable = PointImageDrawable.getOrCreate(view.getContext(),
@ -394,7 +394,8 @@ public class POIMapLayer extends OsmandMapLayer implements ContextMenuLayer.ICon
public int getTextShift(Amenity amenity, RotatedTileBox rb) {
int radiusPoi = getRadiusPoi(rb);
if (isPresentInFullObjects(amenity.getLocation())) {
radiusPoi += (getIconSize(app) - app.getResources().getDimensionPixelSize(R.dimen.favorites_icon_size_small)) / 2;
radiusPoi += (app.getResources().getDimensionPixelSize(R.dimen.favorites_icon_outline_size)
- app.getResources().getDimensionPixelSize(R.dimen.favorites_icon_size_small)) / 2;
}
return radiusPoi;
}

View file

@ -20,6 +20,7 @@ import net.osmand.data.RotatedTileBox;
import net.osmand.data.TransportStop;
import net.osmand.osm.edit.Node;
import net.osmand.osm.edit.Way;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.base.PointImageDrawable;
import net.osmand.plus.settings.backend.CommonPreference;
import net.osmand.plus.settings.backend.OsmandSettings;
@ -181,10 +182,11 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tb, DrawSettings settings) {
List<TransportStop> objects = null;
boolean nightMode = settings.isNightMode();
OsmandApplication app = mapActivity.getMyApplication();
if (tb.getZoom() >= startZoomRoute) {
if (stopRoute != null) {
objects = stopRoute.route.getForwardStops();
int color = stopRoute.getColor(mapActivity.getMyApplication(), nightMode);
int color = stopRoute.getColor(app, nightMode);
attrs.paint.setColor(color);
attrs.updatePaints(view.getApplication(), settings, tb);
try {
@ -217,8 +219,8 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
}
if (objects != null) {
float textScale = mapActivity.getMyApplication().getSettings().TEXT_SCALE.get();
float iconSize = getIconSize(mapActivity) * 3 / 2.5f * textScale;
float textScale = app.getSettings().TEXT_SCALE.get();
float iconSize = getIconSize(app);
QuadTree<QuadRect> boundIntersections = initBoundIntersections(tb);
List<TransportStop> fullObjects = new ArrayList<>();
for (TransportStop o : objects) {
@ -228,7 +230,7 @@ public class TransportStopsLayer extends OsmandMapLayer implements ContextMenuLa
if (intersects(boundIntersections, x, y, iconSize, iconSize)) {
PointImageDrawable pointImageDrawable = PointImageDrawable.getOrCreate(mapActivity,
ContextCompat.getColor(mapActivity, R.color.transport_stop_icon_background),
true,false ,0, BackgroundType.SQUARE);
true, false, 0, BackgroundType.SQUARE);
pointImageDrawable.setAlpha(0.9f);
pointImageDrawable.drawSmallPoint(canvas, x, y, textScale);
} else {