Merge with master

This commit is contained in:
Victor Shcherb 2014-10-25 18:04:40 +02:00
commit fab5fef570
29 changed files with 195 additions and 85 deletions

View file

@ -61,13 +61,13 @@ public class BinaryInspector {
if(args.length == 1 && "test".equals(args[0])) { if(args.length == 1 && "test".equals(args[0])) {
in.inspector(new String[]{ in.inspector(new String[]{
//"-vpoi", //"-vpoi",
"-vmap", "-vmapobjects", // "-vmap", "-vmapobjects",
// "-vrouting", // "-vrouting",
// "-vaddress", "-vcities", "-vstreets", "-vstreetgroups","-vbuildings", // "-vaddress", "-vcities", "-vstreets", "-vstreetgroups","-vbuildings",
//"-zoom=16", //"-zoom=16",
//"-bbox=4,55,7,50", //"-bbox=4,55,7,50",
"/home/victor/projects/osmand/osm-gen/Map.obf" // "/home/victor/projects/osmand/osm-gen/Map.obf"
// "/home/victor/projects/osmand/osm-gen/Netherlands_europe.obf" "/home/victor/projects/osmand/osm-gen/Ukraine_europe.obf"
// "/home/victor/projects/osmand/osm-gen/World_basemap_2_b.obf___" // "/home/victor/projects/osmand/osm-gen/World_basemap_2_b.obf___"
// "/home/victor/projects/osmand/osm-gen/World_basemap_2.obf__" // "/home/victor/projects/osmand/osm-gen/World_basemap_2.obf__"
}); });

View file

@ -14,6 +14,7 @@ public class RenderingRule {
private RenderingRuleProperty[] properties; private RenderingRuleProperty[] properties;
private int[] intProperties; private int[] intProperties;
private RenderingRule[] attributesRef;
private float[] floatProperties; private float[] floatProperties;
private List<RenderingRule> ifElseChildren; private List<RenderingRule> ifElseChildren;
private List<RenderingRule> ifChildren; private List<RenderingRule> ifChildren;
@ -41,6 +42,7 @@ public class RenderingRule {
ArrayList<RenderingRuleProperty> props = new ArrayList<RenderingRuleProperty>(attributes.size()); ArrayList<RenderingRuleProperty> props = new ArrayList<RenderingRuleProperty>(attributes.size());
intProperties = new int[attributes.size()]; intProperties = new int[attributes.size()];
floatProperties = null; floatProperties = null;
attributesRef = null;
int i = 0; int i = 0;
Iterator<Entry<String, String>> it = attributes.entrySet().iterator(); Iterator<Entry<String, String>> it = attributes.entrySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
@ -48,18 +50,23 @@ public class RenderingRule {
RenderingRuleProperty property = storage.PROPS.get(e.getKey()); RenderingRuleProperty property = storage.PROPS.get(e.getKey());
if (property != null) { if (property != null) {
props.add(property); props.add(property);
String vl = e.getValue();
if (property.isString()) { if(vl.startsWith("$")){
intProperties[i] = storage.getDictionaryValue(e.getValue()); if (attributesRef == null) {
attributesRef = new RenderingRule[attributes.size()];
}
attributesRef[i] = storage.getRenderingAttributeRule(vl.substring(1));
} else if (property.isString()) {
intProperties[i] = storage.getDictionaryValue(vl);
} else if (property.isFloat()) { } else if (property.isFloat()) {
if (floatProperties == null) { if (floatProperties == null) {
// lazy creates // lazy creates
floatProperties = new float[attributes.size()]; floatProperties = new float[attributes.size()];
} }
floatProperties[i] = property.parseFloatValue(e.getValue()); floatProperties[i] = property.parseFloatValue(vl);
intProperties[i] = property.parseIntValue(e.getValue()); intProperties[i] = property.parseIntValue(vl);
} else { } else {
intProperties[i] = property.parseIntValue(e.getValue()); intProperties[i] = property.parseIntValue(vl);
} }
i++; i++;
} }
@ -114,6 +121,13 @@ public class RenderingRule {
return intProperties[ind]; return intProperties[ind];
} }
protected RenderingRule getAttrProp(int ind) {
if(attributesRef == null) {
return null;
}
return attributesRef[ind];
}
protected float getFloatProp(int ind){ protected float getFloatProp(int ind){
return floatProperties[ind]; return floatProperties[ind];
} }

View file

@ -157,7 +157,7 @@ public class RenderingRuleSearchRequest {
if(!input) { if(!input) {
return false; return false;
} }
if (!loadOutput) { if (!loadOutput && !rule.isGroup()) {
return true; return true;
} }
// accept it // accept it
@ -171,7 +171,8 @@ public class RenderingRuleSearchRequest {
break; break;
} }
} }
if (match || !rule.isGroup()) { boolean fit = (match || !rule.isGroup());
if (fit && loadOutput) {
if (rule.isGroup()) { if (rule.isGroup()) {
loadOutputProperties(rule, false); loadOutputProperties(rule, false);
} }
@ -179,9 +180,8 @@ public class RenderingRuleSearchRequest {
for (RenderingRule rr : rule.getIfChildren()) { for (RenderingRule rr : rule.getIfChildren()) {
visitRule(rr, loadOutput); visitRule(rr, loadOutput);
} }
return true;
} }
return false; return fit;
} }
@ -191,7 +191,16 @@ public class RenderingRuleSearchRequest {
RenderingRuleProperty rp = properties[i]; RenderingRuleProperty rp = properties[i];
if (rp.isOutputProperty()) { if (rp.isOutputProperty()) {
if (!isSpecified(rp) || override) { if (!isSpecified(rp) || override) {
if (rp.isFloat()) { RenderingRule rr = rule.getAttrProp(i);
if(rr != null) {
visitRule(rr, true);
if(isSpecified(storage.PROPS.R_ATTR_COLOR_VALUE)){
values[rp.getId()] = getIntPropertyValue(storage.PROPS.R_ATTR_COLOR_VALUE);
} else if(isSpecified(storage.PROPS.R_ATTR_INT_VALUE)){
values[rp.getId()] = getIntPropertyValue(storage.PROPS.R_ATTR_INT_VALUE);
fvalues[rp.getId()] = getFloatPropertyValue(storage.PROPS.R_ATTR_INT_VALUE);
}
} else if (rp.isFloat()) {
fvalues[rp.getId()] = rule.getFloatProp(i); fvalues[rp.getId()] = rule.getFloatProp(i);
values[rp.getId()] = rule.getIntProp(i); values[rp.getId()] = rule.getIntProp(i);
} else { } else {

View file

@ -335,11 +335,14 @@ public class RenderingRulesStorage {
String vl = parser.getAttributeValue(i); String vl = parser.getAttributeValue(i);
if (vl != null && vl.startsWith("$")) { if (vl != null && vl.startsWith("$")) {
String cv = vl.substring(1); String cv = vl.substring(1);
if (!renderingConstants.containsKey(cv)) { if (!renderingConstants.containsKey(cv) &&
throw new IllegalStateException("Rendering constant '" + cv + "' was not specified."); !renderingAttributes.containsKey(cv)) {
throw new IllegalStateException("Rendering constant or attribute '" + cv + "' was not specified.");
} }
if(renderingConstants.containsKey(cv)){
vl = renderingConstants.get(cv); vl = renderingConstants.get(cv);
} }
}
m.put(name, vl); m.put(name, vl);
} }
return m; return m;
@ -470,7 +473,7 @@ public class RenderingRulesStorage {
}; };
storage.parseRulesFromXmlInputStream(is, resolver); storage.parseRulesFromXmlInputStream(is, resolver);
printAllRules(storage); // printAllRules(storage);
testSearch(storage); testSearch(storage);
} }
@ -479,22 +482,22 @@ public class RenderingRulesStorage {
// int count = 100000; // int count = 100000;
// for (int i = 0; i < count; i++) { // for (int i = 0; i < count; i++) {
RenderingRuleSearchRequest searchRequest = new RenderingRuleSearchRequest(storage); RenderingRuleSearchRequest searchRequest = new RenderingRuleSearchRequest(storage);
searchRequest.setStringFilter(storage.PROPS.R_TAG, "natural"); searchRequest.setStringFilter(storage.PROPS.R_TAG, "highway");
searchRequest.setStringFilter(storage.PROPS.R_VALUE, "tree"); searchRequest.setStringFilter(storage.PROPS.R_VALUE, "primary");
searchRequest.setStringFilter(storage.PROPS.R_ADDITIONAL, "leaf_type=broadleaved"); // searchRequest.setStringFilter(storage.PROPS.R_ADDITIONAL, "leaf_type=broadleaved");
// searchRequest.setIntFilter(storage.PROPS.R_LAYER, 1); // searchRequest.setIntFilter(storage.PROPS.R_LAYER, 1);
searchRequest.setIntFilter(storage.PROPS.R_MINZOOM, 18); searchRequest.setIntFilter(storage.PROPS.R_MINZOOM, 9);
searchRequest.setIntFilter(storage.PROPS.R_MAXZOOM, 18); searchRequest.setIntFilter(storage.PROPS.R_MAXZOOM, 9);
// searchRequest.setBooleanFilter(storage.PROPS.R_NIGHT_MODE, true); // searchRequest.setBooleanFilter(storage.PROPS.R_NIGHT_MODE, true);
// searchRequest.setBooleanFilter(storage.PROPS.get("hmRendered"), true); // for (RenderingRuleProperty customProp : storage.PROPS.getCustomRules()) {
for (RenderingRuleProperty customProp : storage.PROPS.getCustomRules()) { // if (customProp.isBoolean()) {
if (customProp.isBoolean()) { // searchRequest.setBooleanFilter(customProp, false);
searchRequest.setBooleanFilter(customProp, false); // } else {
} else { // searchRequest.setStringFilter(customProp, "");
searchRequest.setStringFilter(customProp, ""); // }
} // }
} searchRequest.setBooleanFilter(storage.PROPS.get("noPolygons"), true);
boolean res = searchRequest.search(POINT_RULES); boolean res = searchRequest.search(LINE_RULES);
System.out.println("Result " + res); System.out.println("Result " + res);
printResult(searchRequest, System.out); printResult(searchRequest, System.out);
// } // }

View file

@ -1,5 +1,7 @@
package net.osmand.router; package net.osmand.router;
import gnu.trove.set.hash.TLongHashSet;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.BitSet; import java.util.BitSet;
@ -50,6 +52,8 @@ public class GeneralRouter implements VehicleRouter {
// speed in m/s // speed in m/s
private float maxDefaultSpeed = 10; private float maxDefaultSpeed = 10;
private TLongHashSet impassableRoads;
public enum RouteDataObjectAttribute { public enum RouteDataObjectAttribute {
ROAD_SPEED("speed"), ROAD_SPEED("speed"),
@ -180,9 +184,19 @@ public class GeneralRouter implements VehicleRouter {
@Override @Override
public boolean acceptLine(RouteDataObject way) { public boolean acceptLine(RouteDataObject way) {
int res = getObjContext(RouteDataObjectAttribute.ACCESS).evaluateInt(way, 0); int res = getObjContext(RouteDataObjectAttribute.ACCESS).evaluateInt(way, 0);
if(impassableRoads != null && impassableRoads.contains(way.id)) {
return false;
}
return res >= 0; return res >= 0;
} }
public long[] getImpassableRoadIds() {
if(impassableRoads == null) {
return new long[0];
}
return impassableRoads.toArray();
}
private int registerTagValueAttribute(String tag, String value) { private int registerTagValueAttribute(String tag, String value) {
String key = tag +"$"+value; String key = tag +"$"+value;
if(universalRules.containsKey(key)) { if(universalRules.containsKey(key)) {
@ -317,23 +331,23 @@ public class GeneralRouter implements VehicleRouter {
} }
@Override @Override
public double calculateTurnTime(RouteSegment segment, int segmentEnd, RouteSegment prev, int prevSegmentEnd) { public double calculateTurnTime(RouteSegment segment, int segmentEnd, RouteSegment prev, int prevSegmentEnd) {
int[] pt = prev.getRoad().getPointTypes(prevSegmentEnd);
if(pt != null) {
RouteRegion reg = prev.getRoad().region;
for (int i = 0; i < pt.length; i++) {
RouteTypeRule r = reg.quickGetEncodingRule(pt[i]);
if ("highway".equals(r.getTag()) && "traffic_signals".equals(r.getValue())) {
// traffic signals don't add turn info
// return 0;
}
}
}
float ts = getPenaltyTransition(segment.getRoad()); float ts = getPenaltyTransition(segment.getRoad());
float prevTs = getPenaltyTransition(prev.getRoad()); float prevTs = getPenaltyTransition(prev.getRoad());
if(prevTs != ts) { if(prevTs != ts) {
if(ts > prevTs) return (ts - prevTs); if(ts > prevTs) return (ts - prevTs);
} }
// int[] pt = prev.getRoad().getPointTypes(prevSegmentEnd);
// if(pt != null) {
// RouteRegion reg = prev.getRoad().region;
// for (int i = 0; i < pt.length; i++) {
// RouteTypeRule r = reg.quickGetEncodingRule(pt[i]);
// if ("highway".equals(r.getTag()) && "traffic_signals".equals(r.getValue())) {
// // traffic signals don't add turn info
// return 0;
// }
// }
// }
if(segment.getRoad().roundabout() && !prev.getRoad().roundabout()) { if(segment.getRoad().roundabout() && !prev.getRoad().roundabout()) {
double rt = getRoundaboutTurn(); double rt = getRoundaboutTurn();
@ -860,5 +874,14 @@ public class GeneralRouter implements VehicleRouter {
} }
} }
public void addImpassableRoads(TLongHashSet impassableRoads) {
if (impassableRoads != null && !impassableRoads.isEmpty()) {
if (this.impassableRoads == null) {
this.impassableRoads = new TLongHashSet();
}
this.impassableRoads.addAll(impassableRoads);
}
}
} }

View file

@ -1,12 +1,17 @@
package net.osmand.router; package net.osmand.router;
import gnu.trove.set.hash.TLongHashSet;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.binary.RouteDataObject;
import net.osmand.router.GeneralRouter.GeneralRouterProfile; import net.osmand.router.GeneralRouter.GeneralRouterProfile;
import net.osmand.router.GeneralRouter.RouteAttributeContext; import net.osmand.router.GeneralRouter.RouteAttributeContext;
import net.osmand.router.GeneralRouter.RouteDataObjectAttribute; import net.osmand.router.GeneralRouter.RouteDataObjectAttribute;
@ -45,12 +50,18 @@ public class RoutingConfiguration {
public float recalculateDistance = 10000f; public float recalculateDistance = 10000f;
public static class Builder { public static class Builder {
// Design time storage // Design time storage
private String defaultRouter = ""; private String defaultRouter = "";
private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>(); private Map<String, GeneralRouter> routers = new LinkedHashMap<String, GeneralRouter>();
private Map<String, String> attributes = new LinkedHashMap<String, String>(); private Map<String, String> attributes = new LinkedHashMap<String, String>();
private TLongHashSet impassableRoadIds = new TLongHashSet();
private List<RouteDataObject> impassableRoads = new ArrayList<RouteDataObject>();
// Example
// {
// impassableRoadIds.add(23000069L);
// }
public RoutingConfiguration build(String router, int memoryLimitMB) { public RoutingConfiguration build(String router, int memoryLimitMB) {
return build(router, null, memoryLimitMB, null); return build(router, null, memoryLimitMB, null);
@ -76,6 +87,7 @@ public class RoutingConfiguration {
i.initialDirection = direction; i.initialDirection = direction;
i.recalculateDistance = parseSilentFloat(getAttribute(i.router, "recalculateDistanceHelp"), i.recalculateDistance) ; i.recalculateDistance = parseSilentFloat(getAttribute(i.router, "recalculateDistanceHelp"), i.recalculateDistance) ;
i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient); i.heuristicCoefficient = parseSilentFloat(getAttribute(i.router, "heuristicCoefficient"), i.heuristicCoefficient);
i.router.addImpassableRoads(impassableRoadIds);
i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES); i.ZOOM_TO_LOAD_TILES = parseSilentInt(getAttribute(i.router, "zoomToLoadTiles"), i.ZOOM_TO_LOAD_TILES);
int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0); int desirable = parseSilentInt(getAttribute(i.router, "memoryLimitInMB"), 0);
if(desirable != 0) { if(desirable != 0) {
@ -92,6 +104,21 @@ public class RoutingConfiguration {
return i; return i;
} }
public List<RouteDataObject> getImpassableRoads() {
return impassableRoads;
}
public TLongHashSet getImpassableRoadIds() {
return impassableRoadIds;
}
public void addImpassableRoad(RouteDataObject r) {
impassableRoadIds.add(r.id);
impassableRoads.add(r);
}
private String getAttribute(VehicleRouter router, String propertyName) { private String getAttribute(VehicleRouter router, String propertyName) {
if (router.containsAttribute(propertyName)) { if (router.containsAttribute(propertyName)) {
return router.getAttribute(propertyName); return router.getAttribute(propertyName);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<android.opengl.GLSurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/glSurfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</android.opengl.GLSurfaceView>

View file

@ -12,11 +12,11 @@
android:keepScreenOn="true" android:keepScreenOn="true"
android:orientation="vertical" > android:orientation="vertical" >
<android.opengl.GLSurfaceView <ViewStub android:id="@+id/glSurfaceStub"
android:id="@+id/glSurfaceView" android:inflatedId="@+id/glSurfaceView"
android:layout="@layout/gl_surface"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" />
android:visibility="gone" />
<net.osmand.plus.views.OsmAndMapSurfaceView <net.osmand.plus.views.OsmAndMapSurfaceView
android:id="@+id/MapView" android:id="@+id/MapView"

View file

@ -1746,4 +1746,9 @@ s často kladenými otázkami.</string>
<string name="fav_point_emoticons_message">Jméno oblíbeného bodu bylo změněno na %1$s, aby bylo možné uložit název emotikonu do souboru.</string> <string name="fav_point_emoticons_message">Jméno oblíbeného bodu bylo změněno na %1$s, aby bylo možné uložit název emotikonu do souboru.</string>
<string name="speed_limit_exceed">Tolerance překročení rychlosti</string> <string name="speed_limit_exceed">Tolerance překročení rychlosti</string>
<string name="speed_limit_exceed_message">Zvolte toleranci překročení povolené rychlosti, po které uslyšíte hlasové varování.</string> <string name="speed_limit_exceed_message">Zvolte toleranci překročení povolené rychlosti, po které uslyšíte hlasové varování.</string>
<string name="osmo_device_not_found">Zařízení nenalezeno</string>
<string name="osmo_no_connection_msg">Služba OsMo není k dispozici:\n- zkontrolujte připojení;\n- zkontrolujte nastavení;\n- podívejte se na náš Twitter: https://twitter.com/OsMomobi</string>
<string name="anonymous_user_hint">Anonymní uživatel nemůže:\n- vytvářet skupiny;\n- synchronizovat skupiny a zařízení se serverem;\n- manage groups and devices in a private office.</string>
<string name="anonymous_user">Anonymní uživatel</string>
<string name="logged_as">Přihlášen jako %1$s</string>
</resources> </resources>

View file

@ -840,7 +840,7 @@ Nogle af de centrale funktioner:
<string name="m">m</string> <string name="m">m</string>
<string name="old_map_index_is_not_supported">Forældet kortdataformat \'{0}\' er ikke understøttet</string> <string name="old_map_index_is_not_supported">Forældet kortdataformat \'{0}\' er ikke understøttet</string>
<string name="poi_filter_closest_poi">Nærmeste interessepunkt</string> <string name="poi_filter_closest_poi">Nærmeste interessepunkt</string>
<string name="poi_filter_custom_filter">Tilpasset filter</string> <string name="poi_filter_custom_filter">Brugerdefineret filter</string>
<string name="poi_filter_namefinder">Online navne-søger</string> <string name="poi_filter_namefinder">Online navne-søger</string>
<string name="reading_cached_tiles">Læser cachelagrede delkort…</string> <string name="reading_cached_tiles">Læser cachelagrede delkort…</string>
<string name="version_index_is_big_for_memory">Ikke nok hukommelse for indeks \'{0}\'</string> <string name="version_index_is_big_for_memory">Ikke nok hukommelse for indeks \'{0}\'</string>
@ -879,7 +879,7 @@ Nogle af de centrale funktioner:
\n\nFor at få kørselsvejledning til destinationen fra et andet punkt end den aktuelle position, vælges det på kortet, og tryk \'Kørselsvejledning fra\'. \n\nFor at få kørselsvejledning til destinationen fra et andet punkt end den aktuelle position, vælges det på kortet, og tryk \'Kørselsvejledning fra\'.
\n\nVælg enten \'Begynd navigation\', hvilket betyder, at OsmAnd giver vejledning og talte instruktioner (hvis aktiveret) mv. Eller vælg \'Vis rute\', hvilket resulterer i statisk rute uden vejledning eller justeringer, mens du flytter. \n\nVælg enten \'Begynd navigation\', hvilket betyder, at OsmAnd giver vejledning og talte instruktioner (hvis aktiveret) mv. Eller vælg \'Vis rute\', hvilket resulterer i statisk rute uden vejledning eller justeringer, mens du flytter.
\n\nBruges \'Kørselsvejledning fra\' sammen med \'Begynd navigation\', vil OsmAnd skifte til den faktiske position, så snart den er fundet (dette kan bruges til at komme hurtigt i gang med rutevejledning før positionen findes), mens \'Kørselsvejledning fra\' i kombination med \'Vis rute\' kun viser ruten fra ethvert vilkårligt valgt punkt uden efterfølgende opdateringer.\nHvis du bruger \"Kørselsvejledning fra \'sammen med\' Start navigation\", vil Osmand så hurtigt skifte til din aktuelle position som det findes (så dette kan bruges til at kickstarte routing før positionen er fundet), mens \"Kørselsvejledning fra \'i kombination med \'Vis rute\' bare viser dig ruten fra enhver vilkårlig punkt, du havde valgt uden efterfølgende opdateringer. "</string> \n\nBruges \'Kørselsvejledning fra\' sammen med \'Begynd navigation\', vil OsmAnd skifte til den faktiske position, så snart den er fundet (dette kan bruges til at komme hurtigt i gang med rutevejledning før positionen findes), mens \'Kørselsvejledning fra\' i kombination med \'Vis rute\' kun viser ruten fra ethvert vilkårligt valgt punkt uden efterfølgende opdateringer.\nHvis du bruger \"Kørselsvejledning fra \'sammen med\' Start navigation\", vil Osmand så hurtigt skifte til din aktuelle position som det findes (så dette kan bruges til at kickstarte routing før positionen er fundet), mens \"Kørselsvejledning fra \'i kombination med \'Vis rute\' bare viser dig ruten fra enhver vilkårlig punkt, du havde valgt uden efterfølgende opdateringer. "</string>
<string name="amenity_type_landuse">Brug af landområder</string> <string name="amenity_type_landuse">Arealanvendelse</string>
<string name="amenity_type_sustenance">Mad og drikke</string> <string name="amenity_type_sustenance">Mad og drikke</string>
<string name="voice_is_not_available_msg">Talevejledning er ikke tilgængelig. Gå til \'Indstillinger - Datahåndtering\', vælg den ønskede stemmepakke og hent den.</string> <string name="voice_is_not_available_msg">Talevejledning er ikke tilgængelig. Gå til \'Indstillinger - Datahåndtering\', vælg den ønskede stemmepakke og hent den.</string>
<string name="items_were_selected">{0} enheder valgt</string> <string name="items_were_selected">{0} enheder valgt</string>
@ -1832,12 +1832,12 @@ Nogle af de centrale funktioner:
<string name="use_native_render">Brug indbygget optegning</string> <string name="use_native_render">Brug indbygget optegning</string>
<string name="use_native_render_descr">Brug C++ optegning i stedet for Java</string> <string name="use_native_render_descr">Brug C++ optegning i stedet for Java</string>
<string name="print_route">Udskriv rute</string> <string name="print_route">Udskriv rute</string>
<string name="fav_point_emoticons_message">Favoritnavn er ændret til %1$s for korrekt at kan gemme strengen med humørikoner til en fil.</string> <string name="fav_point_emoticons_message">Favoritnavn er ændret til %1$s for at kunne gemme navnet med humørikoner til en fil.</string>
<string name="speed_limit_exceed">Tolerance for hastighedsgrænse</string> <string name="speed_limit_exceed">Tolerance for hastighedsgrænse</string>
<string name="speed_limit_exceed_message">Vælg hastighedsgrænse tolerancen, over hvilken du vil modtage en stemme advarsel.</string> <string name="speed_limit_exceed_message">Vælg hvor meget hastighedsgrænsen skal overskrides, for at få en stemmeadvarsel.</string>
<string name="osmo_device_not_found">Enheden blev ikke fundet</string> <string name="osmo_device_not_found">Enheden blev ikke fundet</string>
<string name="osmo_no_connection_msg">OsMo tjenesten er ikke tilgængelig:\n- check forbindelsen;\n- kontrollere indstillingerne;\n- Tjek vores Twitter: https://twitter.com/OsMomobi</string> <string name="osmo_no_connection_msg">OsMo tjenesten er ikke tilgængelig:\n- kontrollere forbindelsen;\n- kontrollere indstillingerne;\n- se på Twitter: https://twitter.com/OsMomobi</string>
<string name="anonymous_user_hint">En anonym bruger kan ikke:\n- oprette grupper;\n- synkronisere grupper og enheder med serveren;\n- administrere grupper og enheder i et privat kontor.</string> <string name="anonymous_user_hint">En anonym bruger kan ikke:\n- oprette grupper;\n- synkronisere grupper og enheder med serveren;\n- administrere grupper og enheder i et privat område.</string>
<string name="anonymous_user">Anonym bruger</string> <string name="anonymous_user">Anonym bruger</string>
<string name="logged_as">Logget ind som %1$s</string> <string name="logged_as">Logget ind som %1$s</string>
<string name="configure_map">Konfigurer kort</string> <string name="configure_map">Konfigurer kort</string>

View file

@ -1970,7 +1970,7 @@ Afghanistan, Ägypten, Albanien, Algerien, Andorra, Angola, Anguilla, Antigua an
<string name="targets">Ziele</string> <string name="targets">Ziele</string>
<string name="way_alarms">Verkehrswarnungen</string> <string name="way_alarms">Verkehrswarnungen</string>
<string name="record_plugin_description">Speichern Sie Ihre Tracks mit einem Klick. Zeigt die Einstellung, wie Strecken aufgezeichnet werden in lokale GPX-Dateien oder online via Web-Service.</string> <string name="record_plugin_description">Speichern Sie Ihre Tracks mit einem Klick. Zeigt die Einstellung, wie Strecken aufgezeichnet werden in lokale GPX-Dateien oder online via Web-Service.</string>
<string name="route_descr_destination"></string> <string name="route_descr_destination"/>
<string name="local_index_description">Antippen eines Elements um mehr Details zu erfahren, Tippen und Halten zum Deaktivieren oder Löschen des Elements. Aktuell auf dem Gerät vorhandene Daten (%1$s frei):</string> <string name="local_index_description">Antippen eines Elements um mehr Details zu erfahren, Tippen und Halten zum Deaktivieren oder Löschen des Elements. Aktuell auf dem Gerät vorhandene Daten (%1$s frei):</string>
<string name="text_size_descr">Karten-Schriftgröße festlegen</string> <string name="text_size_descr">Karten-Schriftgröße festlegen</string>
<string name="text_size">Schriftgröße</string> <string name="text_size">Schriftgröße</string>
@ -1984,4 +1984,9 @@ Afghanistan, Ägypten, Albanien, Algerien, Andorra, Angola, Anguilla, Antigua an
<string name="print_route">Route drucken</string> <string name="print_route">Route drucken</string>
<string name="speed_limit_exceed">Toleranz für Tempolimit</string> <string name="speed_limit_exceed">Toleranz für Tempolimit</string>
<string name="speed_limit_exceed_message">Schwellenwert für Warnung bei Überschreiten der Höchstgeschwindigkeit.</string> <string name="speed_limit_exceed_message">Schwellenwert für Warnung bei Überschreiten der Höchstgeschwindigkeit.</string>
<string name="osmo_device_not_found">Gerät wurde nicht gefunden</string>
<string name="osmo_no_connection_msg">OsMo-Dienst ist nicht verfügbar:\n- bitte Verbindung prüfen;\n- bitte Einstellungen prüfen;\n- ggf. Meldung auf Twitter: https://twitter.com/OsMomobi</string>
<string name="anonymous_user">Anonymer Benutzer</string>
<string name="logged_as">angemeldet als %1$s</string>
<string name="anonymous_user_hint">Anynyme Benutzer können nicht::\n- Gruppen bilden;\n- Synchronisieren von Gruppen und Geräten auf dem Server;\n- Verwalten von Gruppen und Geräten im Privatbereich.</string>
</resources> </resources>

View file

@ -1673,4 +1673,7 @@
<string name="traffic_warning_speed_camera">Κάμερα ταχύτητας</string> <string name="traffic_warning_speed_camera">Κάμερα ταχύτητας</string>
<string name="text_size_descr">Ορίστε το μέγεθος του κειμένου στο χάρτη.</string> <string name="text_size_descr">Ορίστε το μέγεθος του κειμένου στο χάρτη.</string>
<string name="text_size">Μέγεθος κειμένου</string> <string name="text_size">Μέγεθος κειμένου</string>
<string name="osmo_device_not_found">Η συσκευή δεν βρέθηκε</string>
<string name="anonymous_user">Ανώνυμος χρήστης</string>
<string name="logged_as">Συνδεδεμένος ως %1$s</string>
</resources> </resources>

View file

@ -1549,7 +1549,7 @@ Afganistán, Albania, Alemania, Andorra, Angola, Anguila, Antigua y Barbuda, Ant
<string name="routing_attr_avoid_motorway_name">Evitar autopistas</string> <string name="routing_attr_avoid_motorway_name">Evitar autopistas</string>
<string name="routing_attr_avoid_motorway_description">Evita las autopistas</string> <string name="routing_attr_avoid_motorway_description">Evita las autopistas</string>
<string name="routing_attr_weight_name">Límite de peso</string> <string name="routing_attr_weight_name">Límite de peso</string>
<string name="routing_attr_weight_description">Indicar peso del vehículo permitido en rutas</string> <string name="routing_attr_weight_description">Indicar el peso del vehículo permitido en rutas</string>
<string name="android_19_location_disabled">Desde la versión Android KitKat (4.4), no puedes descargar ni actualizar el mapa en el anterior lugar de almacenamiento (%s). ¿Quieres cambiar a una nueva localización permitida y copiar todos los archivos allí? <string name="android_19_location_disabled">Desde la versión Android KitKat (4.4), no puedes descargar ni actualizar el mapa en el anterior lugar de almacenamiento (%s). ¿Quieres cambiar a una nueva localización permitida y copiar todos los archivos allí?
\n Nota: los archivos antiguos permanecerán intactos. \n Nota: los archivos antiguos permanecerán intactos.
\n Nota: no será posible compartir archivos entre OsmAnd y OsmAnd+. </string> \n Nota: no será posible compartir archivos entre OsmAnd y OsmAnd+. </string>
@ -1882,9 +1882,9 @@ Afganistán, Albania, Alemania, Andorra, Angola, Anguila, Antigua y Barbuda, Ant
<string name="fav_point_dublicate">Nombre de punto favorito duplicado</string> <string name="fav_point_dublicate">Nombre de punto favorito duplicado</string>
<string name="fav_point_dublicate_message">Hemos cambiado el nombre de tu punto favorito a %1$s para evitar nombres duplicados.</string> <string name="fav_point_dublicate_message">Hemos cambiado el nombre de tu punto favorito a %1$s para evitar nombres duplicados.</string>
<string name="test_native_render">Probar renderización nativa</string> <string name="test_native_render">Probar renderización nativa</string>
<string name="test_native_render_msg">Iniciar actividad con renderización nativa</string> <string name="test_native_render_msg">Iniciar la actividad con renderización nativa</string>
<string name="use_native_render">Usar renderización nativa</string> <string name="use_native_render">Usar renderización nativa</string>
<string name="use_native_render_descr">Usar C++ para la renderización en vez de Java</string> <string name="use_native_render_descr">Usar el renderizado C++ en lugar de Java</string>
<string name="print_route">Imprimir ruta</string> <string name="print_route">Imprimir ruta</string>
<string name="fav_point_emoticons_message">El nombre de punto favorito ha sido cambiado a %1$s para facilitar el guardado de la cadena con emoticonos a un archivo.</string> <string name="fav_point_emoticons_message">El nombre de punto favorito ha sido cambiado a %1$s para facilitar el guardado de la cadena con emoticonos a un archivo.</string>
<string name="speed_limit_exceed">Tolerancia de límite de velocidad</string> <string name="speed_limit_exceed">Tolerancia de límite de velocidad</string>

View file

@ -1833,4 +1833,9 @@ Afghanistan, Albanie, Algérie, Allemagne, Andorre, Angola, Anguilla, Antigua-et
<string name="fav_point_emoticons_message">Le nom de votre favoris sera %1$s car il n\'est pas possible d\'utiliser les émoticônes.</string> <string name="fav_point_emoticons_message">Le nom de votre favoris sera %1$s car il n\'est pas possible d\'utiliser les émoticônes.</string>
<string name="speed_limit_exceed">Marge tolérée aux limites de vitesse</string> <string name="speed_limit_exceed">Marge tolérée aux limites de vitesse</string>
<string name="speed_limit_exceed_message">Indiquez la marge à tolérer aux limitations de vitesse avant le déclenchement des annonces vocales.</string> <string name="speed_limit_exceed_message">Indiquez la marge à tolérer aux limitations de vitesse avant le déclenchement des annonces vocales.</string>
<string name="osmo_device_not_found">Périphérique introuvable</string>
<string name="osmo_no_connection_msg">Le service OsMo n\'est pas disponible :\n- Vérifier la connexion;\n- Vérifier les paramètres;\n- Vérifier notre Twitter: https://twitter.com/OsMomobi</string>
<string name="anonymous_user_hint">Un utilisateur anonyme ne peut pas :\n- Créer des groupes;\n- Synchroniser les groupes et les périphériques avec le serveur;\n- Gérer les groupes et les périphériques dans un espace privé.</string>
<string name="anonymous_user">Utilisateur anonyme</string>
<string name="logged_as">Connecté entant que %1$s</string>
</resources> </resources>

View file

@ -289,15 +289,14 @@
\n\nPer ricevere indicazioni partendo da un punto diverso alla tua posizione attuale, seleziona il punto voluto sulla mappa e scegli \'Indicazioni da\'. \n\nPer ricevere indicazioni partendo da un punto diverso alla tua posizione attuale, seleziona il punto voluto sulla mappa e scegli \'Indicazioni da\'.
\n\nSe usi \'Indicazioni da\' insieme ad \'Avvia navigazione\', OsmAnd passerà alla tua posizione attuale on appena essa sarà disponibile (questo modo è stato studiato proprio per permettere di avviare immediatamente la navigazione ancor prima che la posizione sia stata individuata), mentre \'Indicazioni da\' insieme a \'Mostra percorso\' calcola il percorso da un punto arbitrario senza effettuare alcun aggiornamento. "</string> \n\nSe usi \'Indicazioni da\' insieme ad \'Avvia navigazione\', OsmAnd passerà alla tua posizione attuale on appena essa sarà disponibile (questo modo è stato studiato proprio per permettere di avviare immediatamente la navigazione ancor prima che la posizione sia stata individuata), mentre \'Indicazioni da\' insieme a \'Mostra percorso\' calcola il percorso da un punto arbitrario senza effettuare alcun aggiornamento. "</string>
<string name="tip_search">Ricerca</string> <string name="tip_search">Ricerca</string>
<string name="tip_search_t">Puoi cercare i luoghi direttamente sulla mappa attraverso \'Utilizza la posizione\' → \'Cerca nelle vicinanze\', oppure andando in \'Menu\' → \'Ricerca\'. <string name="tip_search_t">"Puoi cercare i luoghi direttamente sulla mappa attraverso \'Utilizza la posizione\' → \'Cerca nelle vicinanze\', oppure andando in \'Menu\' → \'Ricerca\'.
\n\nLa schermata di ricerca fornisce varie schede per effettuare ricerche \n\nLa schermata di ricerca fornisce varie schede per effettuare ricerche
\n\tper indirizzo \n\tper indirizzo
\n\tdalle coordinate \n\tdalle coordinate
\n\tda un PDI (dal tipo o dal nome) \n\tda un PDI (dal tipo o dal nome)
\n\tdalla tua cronologia ricerche \n\tdalla tua cronologia ricerche
\n\toppure fra i tuoi preferiti. \n\toppure fra i tuoi preferiti.
\n\nPer ogni risultato un menù contestuale permetterà di scegliere tra \'Indicazioni\' o \'Visualizza nella mappa\', etc. \n\nPer ogni risultato un menù contestuale permetterà di scegliere tra \'Indicazioni per\' o \'Visualizza nella mappa\', etc. "</string>
</string>
<string name="tip_map_context_menu">Menu \'Utilizza la posizione\'</string> <string name="tip_map_context_menu">Menu \'Utilizza la posizione\'</string>
<string name="tip_map_context_menu_t">Il menu contestuale \'Utilizza la posizione…\' mostra tutte le azioni possibili per un punto (posizione). <string name="tip_map_context_menu_t">Il menu contestuale \'Utilizza la posizione…\' mostra tutte le azioni possibili per un punto (posizione).
\n\nViene visualizzato selezionando a lungo sulla mappa, premendo il pulsante trackball o selezionando \'Menù\' → \'Utilizza la posizione…\' (gli ultimi due modi prendono il centro della mappa come riferimento). \n\nViene visualizzato selezionando a lungo sulla mappa, premendo il pulsante trackball o selezionando \'Menù\' → \'Utilizza la posizione…\' (gli ultimi due modi prendono il centro della mappa come riferimento).
@ -1661,7 +1660,7 @@ Si consiglia di aggiungere uno o più punti intermedi per migliorarne le prestaz
<string name="routing_attr_avoid_motorway_name">Evita le autostrade</string> <string name="routing_attr_avoid_motorway_name">Evita le autostrade</string>
<string name="routing_attr_avoid_motorway_description">Evita le autostrade</string> <string name="routing_attr_avoid_motorway_description">Evita le autostrade</string>
<string name="routing_attr_weight_name">Limite di peso</string> <string name="routing_attr_weight_name">Limite di peso</string>
<string name="routing_attr_weight_description">Specifica il limite di peso del veicolo</string> <string name="routing_attr_weight_description">Specifica il peso del veicolo permesso sul percorso</string>
<string name="select_gpx">Scegli GPX…</string> <string name="select_gpx">Scegli GPX…</string>
<string name="route_descr_select_destination">Scegli la destinazione</string> <string name="route_descr_select_destination">Scegli la destinazione</string>
<string name="route_descr_select_on_map">Scegli sulla mappa…</string> <string name="route_descr_select_on_map">Scegli sulla mappa…</string>
@ -1914,7 +1913,7 @@ Si consiglia di aggiungere uno o più punti intermedi per migliorarne le prestaz
<string name="local_map_names">Nomi locali</string> <string name="local_map_names">Nomi locali</string>
<string name="lang_sw">Swahili</string> <string name="lang_sw">Swahili</string>
<string name="forward">Avanti</string> <string name="forward">Avanti</string>
<string name="home">Home</string> <string name="home">Casa</string>
<string name="live_monitoring_m_descr">Invia il tracciamento a un specifico servizio web se la registrazione GPX è abilitata.</string> <string name="live_monitoring_m_descr">Invia il tracciamento a un specifico servizio web se la registrazione GPX è abilitata.</string>
<string name="live_monitoring_m">Tracciamento online (GPX richiesto)</string> <string name="live_monitoring_m">Tracciamento online (GPX richiesto)</string>
<string name="live_monitoring_start">Avvia il tracciamento online</string> <string name="live_monitoring_start">Avvia il tracciamento online</string>
@ -1941,12 +1940,12 @@ Si consiglia di aggiungere uno o più punti intermedi per migliorarne le prestaz
<string name="osmo_specify_tracker_id">Per favore specifica l\'id</string> <string name="osmo_specify_tracker_id">Per favore specifica l\'id</string>
<string name="continue_navigation">Prosegui la navigazione</string> <string name="continue_navigation">Prosegui la navigazione</string>
<string name="pause_navigation">Metti in pausa la navigazione</string> <string name="pause_navigation">Metti in pausa la navigazione</string>
<string name="rendering_attr_alpineHiking_name">Vista escursionismo alpino</string> <string name="rendering_attr_alpineHiking_name">Scala escursionismo alpino (SAC)</string>
<string name="rendering_attr_alpineHiking_description">Disegna i sentieri in base alla scala SAC</string> <string name="rendering_attr_alpineHiking_description">Disegna i sentieri in base alla scala SAC</string>
<string name="rendering_attr_osmcTraces_name">Strato simboli escursionistici</string> <string name="rendering_attr_osmcTraces_name">Strato simboli escursionistici</string>
<string name="rendering_attr_osmcTraces_description">Disegna i percorsi in base alle tracce OSMC</string> <string name="rendering_attr_osmcTraces_description">Disegna i percorsi in base alle tracce OSMC</string>
<string name="rendering_attr_coloredBuildings_name">Edifici colorati</string> <string name="rendering_attr_coloredBuildings_name">Edifici colorati per tipologia</string>
<string name="arrival_distance_factor_early">Presto</string> <string name="arrival_distance_factor_early">Presto</string>
<string name="arrival_distance_factor_normally">Normale</string> <string name="arrival_distance_factor_normally">Normale</string>
<string name="arrival_distance_factor_late">Tardi</string> <string name="arrival_distance_factor_late">Tardi</string>

View file

@ -2004,4 +2004,9 @@ Afganistan, Albánsko, Alžírsko, Andora, Angola, Anguilla, Antigua a Barbuda,
<string name="print_route">Vytlačiť trasu</string> <string name="print_route">Vytlačiť trasu</string>
<string name="speed_limit_exceed">Tolerancia prekročenia povolenej rýchlosti</string> <string name="speed_limit_exceed">Tolerancia prekročenia povolenej rýchlosti</string>
<string name="speed_limit_exceed_message">Zvoľte toleranciu prekročenia povolenej rýchlosti, po ktorej dostanete hlasové oznámenie.</string> <string name="speed_limit_exceed_message">Zvoľte toleranciu prekročenia povolenej rýchlosti, po ktorej dostanete hlasové oznámenie.</string>
<string name="osmo_device_not_found">Zariadenie sa nenašlo</string>
<string name="anonymous_user">Anonymný používateľ</string>
<string name="logged_as">Prihlásený ako %1$s</string>
<string name="osmo_no_connection_msg">Služba OsMo nie je dostupná:\n- skontrolujte pripojenie;\n- skontrolujte nastavenie;\n- pozrite na náš Twitter: https://twitter.com/OsMomobi</string>
<string name="anonymous_user_hint">Anonymný používateľ nemôže:\n- vytvárať skupiny;\n- synchronizovať skupiny a zariadenia so serverom;\n- spravovať skupiny a zariadenia v súkromnej kancelárii.</string>
</resources> </resources>

View file

@ -1713,4 +1713,6 @@
<string name="anonymous_user_hint">En anonym användare kan inte:\n- skapa grupper;\n- synkronisera grupper och enheter med servern;\n- hantera grupper och enheter i ett privat kontor.</string> <string name="anonymous_user_hint">En anonym användare kan inte:\n- skapa grupper;\n- synkronisera grupper och enheter med servern;\n- hantera grupper och enheter i ett privat kontor.</string>
<string name="anonymous_user">Anonym användare</string> <string name="anonymous_user">Anonym användare</string>
<string name="logged_as">Inloggad som %1$s</string> <string name="logged_as">Inloggad som %1$s</string>
<string name="configure_map">Konfigurera karta</string>
<string name="search_radius_proximity">I närheten av</string>
</resources> </resources>

View file

@ -68,6 +68,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.view.ViewStub;
import android.view.Window; import android.view.Window;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ProgressBar; import android.widget.ProgressBar;
@ -139,8 +140,8 @@ public class MapActivity extends AccessibleActivity {
parseLaunchIntentLocation(); parseLaunchIntentLocation();
if(settings.USE_NATIVE_RENDER.get() && NativeQtLibrary.isInit()) { if(settings.USE_NATIVE_RENDER.get() && NativeQtLibrary.isInit()) {
glSurfaceView = (GLSurfaceView) findViewById(R.id.glSurfaceView); ViewStub stub = (ViewStub) findViewById(R.id.glSurfaceStub);
glSurfaceView.setVisibility(View.VISIBLE); glSurfaceView = (GLSurfaceView) stub.inflate();
OsmAndMapLayersView ml = (OsmAndMapLayersView) findViewById(R.id.MapLayersView); OsmAndMapLayersView ml = (OsmAndMapLayersView) findViewById(R.id.MapLayersView);
ml.setVisibility(View.VISIBLE); ml.setVisibility(View.VISIBLE);
NativeQtLibrary.initView(glSurfaceView); NativeQtLibrary.initView(glSurfaceView);

View file

@ -32,6 +32,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;

View file

@ -241,13 +241,15 @@ public class TextRenderer {
paintText.setColor(text.textShadowColor); paintText.setColor(text.textShadowColor);
paintText.setStyle(Style.STROKE); paintText.setStyle(Style.STROKE);
paintText.setStrokeWidth(2 + text.textShadow); paintText.setStrokeWidth(2 + text.textShadow);
cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText); cv.drawTextOnPath(text.text, text.drawOnPath, 0,
text.vOffset - ( paintText.ascent()/2 + paintText.descent()), paintText);
// reset // reset
paintText.setStyle(Style.FILL); paintText.setStyle(Style.FILL);
paintText.setStrokeWidth(2); paintText.setStrokeWidth(2);
paintText.setColor(text.textColor); paintText.setColor(text.textColor);
} }
cv.drawTextOnPath(text.text, text.drawOnPath, 0, text.vOffset, paintText); cv.drawTextOnPath(text.text, text.drawOnPath, 0,
text.vOffset - ( paintText.ascent()/2 + paintText.descent()), paintText);
} else { } else {
if (text.shieldRes != null) { if (text.shieldRes != null) {
float coef = rc.getDensityValue(rc.screenDensityRatio * rc.textScale); float coef = rc.getDensityValue(rc.screenDensityRatio * rc.textScale);
@ -513,7 +515,6 @@ public class TextRenderer {
p.centerX = points[startInd].x + scale * px + ox; p.centerX = points[startInd].x + scale * px + ox;
p.centerY = points[startInd].y + scale * py + oy; p.centerY = points[startInd].y + scale * py + oy;
p.vOffset += p.textSize / 2 - 1;
// p.hOffset = 0; // p.hOffset = 0;
if (inverse) { if (inverse) {