diff --git a/README.md b/README.md
index cecb125..4f6f9d3 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,9 @@
+Forked from https://github.com/abrensch/brouter
+
+- changed processUnused to true for safety, shortest, and trekking
+- added lts_score to lookups.dat
+
+
BRouter
=======
diff --git a/brouter-core/src/main/java/btools/router/FormatGpx.java b/brouter-core/src/main/java/btools/router/FormatGpx.java
index c652a0a..1d0b88c 100644
--- a/brouter-core/src/main/java/btools/router/FormatGpx.java
+++ b/brouter-core/src/main/java/btools/router/FormatGpx.java
@@ -197,25 +197,32 @@ public class FormatGpx extends Formatter {
for (int i = 0; i <= t.pois.size() - 1; i++) {
OsmNodeNamed poi = t.pois.get(i);
- formatWaypointGpx(sb, poi);
+ formatWaypointGpx(sb, poi, "poi");
}
if (t.exportWaypoints) {
for (int i = 0; i <= t.matchedWaypoints.size() - 1; i++) {
MatchedWaypoint wt = t.matchedWaypoints.get(i);
- sb.append(" \n")
- .append(" ").append(StringUtils.escapeXml10(wt.name)).append("\n");
if (i == 0) {
- sb.append(" from\n");
+ formatWaypointGpx(sb, wt, "from");
} else if (i == t.matchedWaypoints.size() - 1) {
- sb.append(" to\n");
+ formatWaypointGpx(sb, wt, "to");
} else {
- sb.append(" via\n");
+ formatWaypointGpx(sb, wt, "via");
}
- sb.append(" \n");
}
}
+ if (t.exportCorrectedWaypoints) {
+ for (int i = 0; i <= t.matchedWaypoints.size() - 1; i++) {
+ MatchedWaypoint wt = t.matchedWaypoints.get(i);
+ if (wt.correctedpoint != null) {
+ OsmNodeNamed n = new OsmNodeNamed(wt.correctedpoint);
+ n.name = wt.name + "_corr";
+ formatWaypointGpx(sb, n, "via_corr");
+ }
+ }
+ }
+
sb.append(" \n");
if (turnInstructionMode == 9
|| turnInstructionMode == 2
@@ -454,7 +461,7 @@ public class FormatGpx extends Formatter {
StringWriter sw = new StringWriter(8192);
BufferedWriter bw = new BufferedWriter(sw);
formatGpxHeader(bw);
- formatWaypointGpx(bw, n);
+ formatWaypointGpx(bw, n, null);
formatGpxFooter(bw);
bw.close();
sw.close();
@@ -477,7 +484,7 @@ public class FormatGpx extends Formatter {
sb.append("\n");
}
- public void formatWaypointGpx(BufferedWriter sb, OsmNodeNamed n) throws IOException {
+ public void formatWaypointGpx(BufferedWriter sb, OsmNodeNamed n, String type) throws IOException {
sb.append(" ");
if (n.getSElev() != Short.MIN_VALUE) {
@@ -489,6 +496,24 @@ public class FormatGpx extends Formatter {
if (n.nodeDescription != null && rc != null) {
sb.append("").append(rc.expctxWay.getKeyValueDescription(false, n.nodeDescription)).append("");
}
+ if (type != null) {
+ sb.append("").append(type).append("");
+ }
+ sb.append("\n");
+ }
+
+ public void formatWaypointGpx(BufferedWriter sb, MatchedWaypoint wp, String type) throws IOException {
+ sb.append(" ");
+ if (wp.waypoint.getSElev() != Short.MIN_VALUE) {
+ sb.append("").append("" + wp.waypoint.getElev()).append("");
+ }
+ if (wp.name != null) {
+ sb.append("").append(StringUtils.escapeXml10(wp.name)).append("");
+ }
+ if (type != null) {
+ sb.append("").append(type).append("");
+ }
sb.append("\n");
}
diff --git a/brouter-core/src/main/java/btools/router/FormatJson.java b/brouter-core/src/main/java/btools/router/FormatJson.java
index 53f0b4a..d5ba17b 100644
--- a/brouter-core/src/main/java/btools/router/FormatJson.java
+++ b/brouter-core/src/main/java/btools/router/FormatJson.java
@@ -126,7 +126,7 @@ public class FormatJson extends Formatter {
sb.append(" ]\n");
sb.append(" }\n");
- if (t.exportWaypoints || !t.pois.isEmpty()) {
+ if (t.exportWaypoints || t.exportCorrectedWaypoints || !t.pois.isEmpty()) {
sb.append(" },\n");
for (int i = 0; i <= t.pois.size() - 1; i++) {
OsmNodeNamed poi = t.pois.get(i);
@@ -137,6 +137,7 @@ public class FormatJson extends Formatter {
sb.append(" \n");
}
if (t.exportWaypoints) {
+ if (!t.pois.isEmpty()) sb.append(" ,\n");
for (int i = 0; i <= t.matchedWaypoints.size() - 1; i++) {
String type;
if (i == 0) {
@@ -155,6 +156,23 @@ public class FormatJson extends Formatter {
sb.append(" \n");
}
}
+ if (t.exportCorrectedWaypoints) {
+ if (t.exportWaypoints) sb.append(" ,\n");
+ boolean hasCorrPoints = false;
+ for (int i = 0; i <= t.matchedWaypoints.size() - 1; i++) {
+ String type = "via_corr";
+
+ MatchedWaypoint wp = t.matchedWaypoints.get(i);
+ if (wp.correctedpoint != null) {
+ if (hasCorrPoints) {
+ sb.append(",");
+ }
+ addFeature(sb, type, wp.name + "_corr", wp.correctedpoint.ilat, wp.correctedpoint.ilon, wp.correctedpoint.getSElev());
+ sb.append(" \n");
+ hasCorrPoints = true;
+ }
+ }
+ }
} else {
sb.append(" }\n");
}
diff --git a/brouter-core/src/main/java/btools/router/FormatKml.java b/brouter-core/src/main/java/btools/router/FormatKml.java
index 5798c5c..931689a 100644
--- a/brouter-core/src/main/java/btools/router/FormatKml.java
+++ b/brouter-core/src/main/java/btools/router/FormatKml.java
@@ -1,5 +1,6 @@
package btools.router;
+import java.util.ArrayList;
import java.util.List;
import btools.mapaccess.MatchedWaypoint;
@@ -43,7 +44,7 @@ public class FormatKml extends Formatter {
sb.append(" \n");
sb.append(" \n");
sb.append(" \n");
- if (t.exportWaypoints || !t.pois.isEmpty()) {
+ if (t.exportWaypoints || t.exportCorrectedWaypoints || !t.pois.isEmpty()) {
if (!t.pois.isEmpty()) {
sb.append(" \n");
sb.append(" poi\n");
@@ -62,6 +63,19 @@ public class FormatKml extends Formatter {
}
createFolder(sb, "end", t.matchedWaypoints.subList(size - 1, size));
}
+ if (t.exportCorrectedWaypoints) {
+ List list = new ArrayList<>();
+ for (int i = 0; i < t.matchedWaypoints.size(); i++) {
+ MatchedWaypoint wp = t.matchedWaypoints.get(i);
+ if (wp.correctedpoint != null) {
+ OsmNodeNamed n = new OsmNodeNamed(wp.correctedpoint);
+ n.name = wp.name + "_corr";
+ list.add(n);
+ }
+ }
+ int size = list.size();
+ createViaFolder(sb, "via_corr", list.subList(0, size));
+ }
}
sb.append(" \n");
sb.append("\n");
@@ -79,6 +93,17 @@ public class FormatKml extends Formatter {
sb.append(" \n");
}
+ private void createViaFolder(StringBuilder sb, String type, List waypoints) {
+ if (waypoints.isEmpty()) return;
+ sb.append(" \n");
+ sb.append(" " + type + "\n");
+ for (int i = 0; i < waypoints.size(); i++) {
+ OsmNodeNamed wp = waypoints.get(i);
+ createPlaceMark(sb, wp.name, wp.ilat, wp.ilon);
+ }
+ sb.append(" \n");
+ }
+
private void createPlaceMark(StringBuilder sb, String name, int ilat, int ilon) {
sb.append(" \n");
sb.append(" " + StringUtils.escapeXml10(name) + "\n");
diff --git a/brouter-core/src/main/java/btools/router/OsmTrack.java b/brouter-core/src/main/java/btools/router/OsmTrack.java
index ccc232a..848493b 100644
--- a/brouter-core/src/main/java/btools/router/OsmTrack.java
+++ b/brouter-core/src/main/java/btools/router/OsmTrack.java
@@ -23,8 +23,8 @@ import btools.util.CompactLongMap;
import btools.util.FrozenLongMap;
public final class OsmTrack {
- final public static String version = "1.7.7";
- final public static String versionDate = "23072024";
+ final public static String version = "1.7.8";
+ final public static String versionDate = "12072025";
// csv-header-line
private static final String MESSAGES_HEADER = "Longitude\tLatitude\tElevation\tDistance\tCostPerKm\tElevCost\tTurnCost\tNodeCost\tInitialCost\tWayTags\tNodeTags\tTime\tEnergy";
@@ -62,6 +62,7 @@ public final class OsmTrack {
protected List matchedWaypoints;
public boolean exportWaypoints = false;
+ public boolean exportCorrectedWaypoints = false;
public void addNode(OsmPathElement node) {
nodes.add(0, node);
@@ -338,6 +339,7 @@ public final class OsmTrack {
}
float t0 = ourSize > 0 ? nodes.get(ourSize - 1).getTime() : 0;
float e0 = ourSize > 0 ? nodes.get(ourSize - 1).getEnergy() : 0;
+ int c0 = ourSize > 0 ? nodes.get(ourSize - 1).cost : 0;
for (i = 0; i < t.nodes.size(); i++) {
OsmPathElement e = t.nodes.get(i);
if (i == 0 && ourSize > 0 && nodes.get(ourSize - 1).getSElev() == Short.MIN_VALUE)
@@ -345,6 +347,7 @@ public final class OsmTrack {
if (i > 0 || ourSize == 0) {
e.setTime(e.getTime() + t0);
e.setEnergy(e.getEnergy() + e0);
+ e.cost = e.cost + c0;
if (e.message != null){
if (!(e.message.lon == e.getILon() && e.message.lat == e.getILat())) {
e.message.lon = e.getILon();
diff --git a/brouter-core/src/main/java/btools/router/RoutingContext.java b/brouter-core/src/main/java/btools/router/RoutingContext.java
index f5b2bf3..792014c 100644
--- a/brouter-core/src/main/java/btools/router/RoutingContext.java
+++ b/brouter-core/src/main/java/btools/router/RoutingContext.java
@@ -77,6 +77,7 @@ public final class RoutingContext {
public double waypointCatchingRange;
public boolean correctMisplacedViaPoints;
public double correctMisplacedViaPointsDistance;
+ public boolean continueStraight;
public boolean useDynamicDistance;
public boolean buildBeelineOnRange;
@@ -126,6 +127,8 @@ public final class RoutingContext {
correctMisplacedViaPoints = 0.f != expctxGlobal.getVariableValue("correctMisplacedViaPoints", 1.f);
correctMisplacedViaPointsDistance = expctxGlobal.getVariableValue("correctMisplacedViaPointsDistance", 0.f); // 0 == don't use distance
+ continueStraight = 0.f != expctxGlobal.getVariableValue("continueStraight", 0.f);
+
// process tags not used in the profile (to have them in the data-tab)
processUnusedTags = 0.f != expctxGlobal.getVariableValue("processUnusedTags", 0.f);
@@ -221,6 +224,7 @@ public final class RoutingContext {
public String outputFormat = "gpx";
public boolean exportWaypoints = false;
+ public boolean exportCorrectedWaypoints = false;
public OsmPrePath firstPrePath;
diff --git a/brouter-core/src/main/java/btools/router/RoutingEngine.java b/brouter-core/src/main/java/btools/router/RoutingEngine.java
index 698bc7b..42ae5a1 100644
--- a/brouter-core/src/main/java/btools/router/RoutingEngine.java
+++ b/brouter-core/src/main/java/btools/router/RoutingEngine.java
@@ -23,6 +23,7 @@ import btools.mapaccess.OsmLinkHolder;
import btools.mapaccess.OsmNode;
import btools.mapaccess.OsmNodePairSet;
import btools.mapaccess.OsmPos;
+import btools.util.CheapAngleMeter;
import btools.util.CheapRuler;
import btools.util.CompactLongMap;
import btools.util.SortedHeap;
@@ -262,6 +263,7 @@ public class RoutingEngine extends Thread {
}
oldTrack = null;
track.exportWaypoints = routingContext.exportWaypoints;
+ track.exportCorrectedWaypoints = routingContext.exportCorrectedWaypoints;
filename = outfileBase + i + "." + routingContext.outputFormat;
switch (routingContext.outputFormat) {
case "gpx":
@@ -975,6 +977,10 @@ public class RoutingEngine extends Thread {
hasDirectRouting = true;
}
}
+ for (MatchedWaypoint mwp : matchedWaypoints) {
+ //System.out.println(FormatGpx.getWaypoint(mwp.waypoint.ilon, mwp.waypoint.ilat, mwp.name, null));
+ //System.out.println(FormatGpx.getWaypoint(mwp.crosspoint.ilon, mwp.crosspoint.ilat, mwp.name+"_cp", null));
+ }
routingContext.hasDirectRouting = hasDirectRouting;
@@ -995,7 +1001,7 @@ public class RoutingEngine extends Thread {
} else {
seg = searchTrack(matchedWaypoints.get(i), matchedWaypoints.get(i + 1), i == matchedWaypoints.size() - 2 ? nearbyTrack : null, refTracks[i]);
wptIndex = i;
- if (engineMode == BROUTER_ENGINEMODE_ROUNDTRIP) {
+ if (routingContext.continueStraight) {
if (i < matchedWaypoints.size() - 2) {
OsmNode lastPoint = seg.containsNode(matchedWaypoints.get(i+1).node1) ? matchedWaypoints.get(i+1).node1 : matchedWaypoints.get(i+1).node2;
OsmNodeNamed nogo = new OsmNodeNamed(lastPoint);
@@ -1015,7 +1021,7 @@ public class RoutingEngine extends Thread {
boolean changed = false;
if (routingContext.correctMisplacedViaPoints && !matchedWaypoints.get(i).direct && !routingContext.allowSamewayback) {
- changed = snappPathConnection(totaltrack, seg, routingContext.inverseRouting ? matchedWaypoints.get(i + 1) : matchedWaypoints.get(i));
+ changed = snapPathConnection(totaltrack, seg, routingContext.inverseRouting ? matchedWaypoints.get(i + 1) : matchedWaypoints.get(i));
}
if (wptIndex > 0)
matchedWaypoints.get(wptIndex).indexInTrack = totaltrack.nodes.size() - 1;
@@ -1038,12 +1044,198 @@ public class RoutingEngine extends Thread {
if (routingContext.poipoints != null)
totaltrack.pois = routingContext.poipoints;
- totaltrack.matchedWaypoints = matchedWaypoints;
+
return totaltrack;
}
+ OsmTrack getExtraSegment(OsmPathElement start, OsmPathElement end) {
+
+ List wptlist = new ArrayList<>();
+ MatchedWaypoint wpt1 = new MatchedWaypoint();
+ wpt1.waypoint = new OsmNode(start.getILon(), start.getILat());
+ wpt1.name = "wptx1";
+ wpt1.crosspoint = new OsmNode(start.getILon(), start.getILat());
+ wpt1.node1 = new OsmNode(start.getILon(), start.getILat());
+ wpt1.node2 = new OsmNode(end.getILon(), end.getILat());
+ wptlist.add(wpt1);
+ MatchedWaypoint wpt2 = new MatchedWaypoint();
+ wpt2.waypoint = new OsmNode(end.getILon(), end.getILat());
+ wpt2.name = "wptx2";
+ wpt2.crosspoint = new OsmNode(end.getILon(), end.getILat());
+ wpt2.node2 = new OsmNode(start.getILon(), start.getILat());
+ wpt2.node1 = new OsmNode(end.getILon(), end.getILat());
+ wptlist.add(wpt2);
+
+ MatchedWaypoint mwp1 = wptlist.get(0);
+ MatchedWaypoint mwp2 = wptlist.get(1);
+
+ OsmTrack mid = null;
+
+ boolean corr = routingContext.correctMisplacedViaPoints;
+ routingContext.correctMisplacedViaPoints = false;
+
+ guideTrack = new OsmTrack();
+ guideTrack.addNode(start);
+ guideTrack.addNode(end);
+
+ mid = findTrack("getinfo", mwp1, mwp2, null, null, false);
+
+ guideTrack = null;
+ routingContext.correctMisplacedViaPoints = corr;
+
+ return mid;
+ }
+
+ private int snapRoundaboutConnection(OsmTrack tt, OsmTrack t, int indexStart, int indexEnd, int indexMeeting, MatchedWaypoint startWp) {
+
+ int indexMeetingBack = (indexMeeting == -1 ? tt.nodes.size() - 1 : indexMeeting);
+ int indexMeetingFore = 0;
+ int indexStartBack = indexStart;
+ int indexStartFore = 0;
+
+ OsmPathElement ptStart = tt.nodes.get(indexStartBack);
+ OsmPathElement ptMeeting = tt.nodes.get(indexMeetingBack);
+ OsmPathElement ptEnd = t.nodes.get(indexEnd);
+
+ boolean bMeetingIsOnRoundabout = ptMeeting.message.isRoundabout();
+ boolean bMeetsRoundaboutStart = false;
+
+ int i;
+ for (i = 0; i < indexEnd; i++) {
+ OsmPathElement n = t.nodes.get(i);
+ if (n.positionEquals(ptStart)) {
+ indexStartFore = i;
+ bMeetsRoundaboutStart = true;
+ }
+ if (n.positionEquals(ptMeeting)) {
+ indexMeetingFore = i;
+ }
+
+ }
+
+ if (!bMeetsRoundaboutStart && bMeetingIsOnRoundabout) {
+ indexEnd = indexMeetingFore;
+ }
+ if (bMeetsRoundaboutStart && bMeetingIsOnRoundabout) {
+ indexEnd = indexStartFore;
+ }
+
+ List removeList = new ArrayList<>();
+ if (!bMeetsRoundaboutStart) {
+ indexStartBack = indexMeetingBack;
+ while (!tt.nodes.get(indexStartBack).message.isRoundabout()) {
+ indexStartBack--;
+ if (indexStartBack == 2) break;
+ }
+ }
+
+ for (i = indexStartBack + 1; i < tt.nodes.size(); i++) {
+ OsmPathElement n = tt.nodes.get(i);
+ OsmTrack.OsmPathElementHolder detours = tt.getFromDetourMap(n.getIdFromPos());
+ OsmTrack.OsmPathElementHolder h = detours;
+ while (h != null) {
+ h = h.nextHolder;
+ }
+ removeList.add(n);
+ }
+
+ OsmPathElement ttend = null;
+ OsmPathElement ttend_next = null;
+ if (!bMeetingIsOnRoundabout && !bMeetsRoundaboutStart) {
+ ttend = tt.nodes.get(indexStartBack);
+ ttend_next = tt.nodes.get(indexStartBack + 1);
+ OsmTrack.OsmPathElementHolder ttend_detours = tt.getFromDetourMap(ttend.getIdFromPos());
+
+ tt.registerDetourForId(ttend.getIdFromPos(), null);
+ }
+
+ for (OsmPathElement e : removeList) {
+ tt.nodes.remove(e);
+ }
+ removeList.clear();
+
+
+ for (i = 0; i < indexEnd; i++) {
+ OsmPathElement n = t.nodes.get(i);
+ if (n.positionEquals(bMeetsRoundaboutStart ? ptStart : ptEnd)) break;
+ if (!bMeetingIsOnRoundabout && !bMeetsRoundaboutStart && n.message.isRoundabout()) break;
+
+ OsmTrack.OsmPathElementHolder detours = t.getFromDetourMap(n.getIdFromPos());
+ OsmTrack.OsmPathElementHolder h = detours;
+ while (h != null) {
+ h = h.nextHolder;
+ }
+ removeList.add(n);
+ }
+
+ // time hold
+ float atime = 0;
+ float aenergy = 0;
+ int acost = 0;
+ if (i > 1) {
+ atime = t.nodes.get(i).getTime();
+ aenergy = t.nodes.get(i).getEnergy();
+ acost = t.nodes.get(i).cost;
+ }
+
+ for (OsmPathElement e : removeList) {
+ t.nodes.remove(e);
+ }
+ removeList.clear();
+
+ if (atime > 0f) {
+ for (OsmPathElement e : t.nodes) {
+ e.setTime(e.getTime() - atime);
+ e.setEnergy(e.getEnergy() - aenergy);
+ e.cost = e.cost - acost;
+ }
+ }
+
+ if (!bMeetingIsOnRoundabout && !bMeetsRoundaboutStart) {
+
+ OsmPathElement tstart = t.nodes.get(0);
+ OsmPathElement tstart_next = null;
+ OsmTrack.OsmPathElementHolder tstart_detours = t.getFromDetourMap(tstart.getIdFromPos());
+ OsmTrack.OsmPathElementHolder ttend_detours = tt.getFromDetourMap(ttend.getIdFromPos());
+
+ OsmTrack mid = getExtraSegment(ttend, ttend_detours.node);
+ OsmPathElement tt_end = tt.nodes.get(tt.nodes.size() - 1);
+
+ int last_cost = tt_end.cost;
+ int tmp_cost = 0;
+
+ if (mid != null) {
+ boolean start = false;
+ for (OsmPathElement e : mid.nodes) {
+ if (start) {
+ if (e.positionEquals(ttend_detours.node)) {
+ tmp_cost = e.cost;
+ break;
+ }
+ e.cost = last_cost + e.cost;
+ tt.nodes.add(e);
+ }
+ if (e.positionEquals(tt_end)) start = true;
+ }
+
+ }
+
+ ttend_detours.node.cost = last_cost + tmp_cost;
+ tt.nodes.add(ttend_detours.node);
+ t.nodes.add(0, ttend_detours.node);
+
+ }
+
+ tt.cost = tt.nodes.get(tt.nodes.size()-1).cost;
+ t.cost = t.nodes.get(t.nodes.size()-1).cost;
+
+ startWp.correctedpoint = new OsmNode(ptStart.getILon(), ptStart.getILat());
+
+ return (t.nodes.size());
+ }
+
// check for way back on way point
- private boolean snappPathConnection(OsmTrack tt, OsmTrack t, MatchedWaypoint startWp) {
+ private boolean snapPathConnection(OsmTrack tt, OsmTrack t, MatchedWaypoint startWp) {
if (!startWp.name.startsWith("via") && !startWp.name.startsWith("rt"))
return false;
@@ -1075,29 +1267,88 @@ public class RoutingEngine extends Thread {
OsmPathElement newTarget = null;
OsmPathElement tmpback = null;
OsmPathElement tmpfore = null;
+ OsmPathElement tmpStart = null;
int indexback = ourSize - 1;
int indexfore = 0;
int stop = (indexback - MAX_STEPS_CHECK > 1 ? indexback - MAX_STEPS_CHECK : 1);
double wayDistance = 0;
double nextDist = 0;
+ boolean bCheckRoundAbout = false;
+ boolean bBackRoundAbout = false;
+ boolean bForeRoundAbout = false;
+ int indexBackFound = 0;
+ int indexForeFound = 0;
+ int differentLanePoints = 0;
+ int indexMeeting = -1;
+ while (indexback >= 1 && indexback >= stop && indexfore < t.nodes.size()) {
+ tmpback = tt.nodes.get(indexback);
+ tmpfore = t.nodes.get(indexfore);
+ if (!bBackRoundAbout && tmpback.message != null && tmpback.message.isRoundabout()) {
+ bBackRoundAbout = true;
+ indexBackFound = indexfore;
+ }
+ if (!bForeRoundAbout &&
+ tmpfore.message != null && tmpfore.message.isRoundabout() ||
+ (tmpback.positionEquals(tmpfore) && tmpback.message.isRoundabout())) {
+ bForeRoundAbout = true;
+ indexForeFound = indexfore;
+ }
+ if (indexfore == 0) {
+ tmpStart = t.nodes.get(0);
+ } else {
+ double dirback = CheapAngleMeter.getDirection(tmpStart.getILon(), tmpStart.getILat(), tmpback.getILon(), tmpback.getILat());
+ double dirfore = CheapAngleMeter.getDirection(tmpStart.getILon(), tmpStart.getILat(), tmpfore.getILon(), tmpfore.getILat());
+ double dirdiff = CheapAngleMeter.getDifferenceFromDirection(dirback, dirfore);
+ // walking wrong direction
+ if (dirdiff > 60 && !bBackRoundAbout && !bForeRoundAbout) break;
+ }
+ // seems no roundabout, only on one end
+ if (bBackRoundAbout != bForeRoundAbout && indexfore - Math.abs(indexForeFound - indexBackFound) > 8) break;
+ if (!tmpback.positionEquals(tmpfore)) differentLanePoints++;
+ if (tmpback.positionEquals(tmpfore)) indexMeeting = indexback;
+ bCheckRoundAbout = bBackRoundAbout && bForeRoundAbout;
+ if (bCheckRoundAbout) break;
+ indexback--;
+ indexfore++;
+ }
+ //System.out.println("snap round result " + indexback + ": " + bBackRoundAbout + " - " + indexfore + "; " + bForeRoundAbout + " pts " + differentLanePoints);
+ if (bCheckRoundAbout) {
+
+ tmpback = tt.nodes.get(--indexback);
+ while (tmpback.message != null && tmpback.message.isRoundabout()) {
+ tmpback = tt.nodes.get(--indexback);
+ }
+
+ int ifore = ++indexfore;
+ OsmPathElement testfore = t.nodes.get(ifore);
+ while (ifore < t.nodes.size() && testfore.message != null && testfore.message.isRoundabout()) {
+ testfore = t.nodes.get(ifore);
+ ifore++;
+ }
+
+ snapRoundaboutConnection(tt, t, indexback, --ifore, indexMeeting, startWp);
+
+ // remove filled arrays
+ removeVoiceHintList.clear();
+ removeBackList.clear();
+ removeForeList.clear();
+ return true;
+ }
+ indexback = ourSize - 1;
+ indexfore = 0;
while (indexback >= 1 && indexback >= stop && indexfore < t.nodes.size()) {
int junctions = 0;
tmpback = tt.nodes.get(indexback);
tmpfore = t.nodes.get(indexfore);
if (tmpback.message != null && tmpback.message.isRoundabout()) {
- removeBackList.clear();
- removeForeList.clear();
- removeVoiceHintList.clear();
- return false;
+ bCheckRoundAbout = true;
}
if (tmpfore.message != null && tmpfore.message.isRoundabout()) {
- removeBackList.clear();
- removeForeList.clear();
- removeVoiceHintList.clear();
- return false;
+ bCheckRoundAbout = true;
}
- int dist = tmpback.calcDistance(tmpfore);
- if (1 == 1) {
+ {
+
+ int dist = tmpback.calcDistance(tmpfore);
OsmTrack.OsmPathElementHolder detours = tt.getFromDetourMap(tmpback.getIdFromPos());
OsmTrack.OsmPathElementHolder h = detours;
while (h != null) {
@@ -1105,48 +1356,56 @@ public class RoutingEngine extends Thread {
lastJunctions.put(h.node.getIdFromPos(), h);
h = h.nextHolder;
}
- }
- if (dist == 1 && indexfore > 0) {
- if (indexfore == 1) {
- removeBackList.add(tt.nodes.get(tt.nodes.size() - 1)); // last and first should be equal, so drop only on second also equal
- removeForeList.add(t.nodes.get(0));
- removeBackList.add(tmpback);
- removeForeList.add(tmpfore);
- removeVoiceHintList.add(tt.nodes.size() - 1);
- removeVoiceHintList.add(indexback);
- } else {
- removeBackList.add(tmpback);
- removeForeList.add(tmpfore);
- removeVoiceHintList.add(indexback);
- }
- nextDist = t.nodes.get(indexfore - 1).calcDistance(tmpfore);
- wayDistance += nextDist;
- }
- if (dist > 1 || indexback == 1) {
- if (removeBackList.size() != 0) {
- // recover last - should be the cross point
- removeBackList.remove(removeBackList.get(removeBackList.size() - 1));
- removeForeList.remove(removeForeList.get(removeForeList.size() - 1));
- break;
- } else {
+ if (dist == 1 && indexfore > 0) {
+ if (indexfore == 1) {
+ removeBackList.add(tt.nodes.get(tt.nodes.size() - 1)); // last and first should be equal, so drop only on second also equal
+ removeForeList.add(t.nodes.get(0));
+ removeBackList.add(tmpback);
+ removeForeList.add(tmpfore);
+ removeVoiceHintList.add(tt.nodes.size() - 1);
+ removeVoiceHintList.add(indexback);
+ } else {
+ removeBackList.add(tmpback);
+ removeForeList.add(tmpfore);
+ removeVoiceHintList.add(indexback);
+ }
+ nextDist = t.nodes.get(indexfore - 1).calcDistance(tmpfore);
+ wayDistance += nextDist;
+
+ }
+ if (dist > 1 || indexback == 1) {
+ if (removeBackList.size() != 0) {
+ // recover last - should be the cross point
+ removeBackList.remove(removeBackList.get(removeBackList.size() - 1));
+ removeForeList.remove(removeForeList.get(removeForeList.size() - 1));
+ break;
+ } else {
+ return false;
+ }
+ }
+ indexback--;
+ indexfore++;
+
+ if (routingContext.correctMisplacedViaPointsDistance > 0 &&
+ wayDistance > routingContext.correctMisplacedViaPointsDistance) {
+ removeVoiceHintList.clear();
+ removeBackList.clear();
+ removeForeList.clear();
return false;
}
}
- indexback--;
- indexfore++;
-
- if (routingContext.correctMisplacedViaPointsDistance > 0 &&
- wayDistance > routingContext.correctMisplacedViaPointsDistance) break;
}
// time hold
float atime = 0;
float aenergy = 0;
+ int acost = 0;
if (removeForeList.size() > 1) {
- atime = t.nodes.get(removeForeList.size() - 2).getTime();
- aenergy = t.nodes.get(removeForeList.size() - 2).getEnergy();
+ atime = t.nodes.get(indexfore -1).getTime();
+ aenergy = t.nodes.get(indexfore -1).getEnergy();
+ acost = t.nodes.get(indexfore -1).cost;
}
for (OsmPathElement e : removeBackList) {
@@ -1166,6 +1425,7 @@ public class RoutingEngine extends Thread {
for (OsmPathElement e : t.nodes) {
e.setTime(e.getTime() - atime);
e.setEnergy(e.getEnergy() - aenergy);
+ e.cost = e.cost - acost;
}
}
@@ -1181,35 +1441,17 @@ public class RoutingEngine extends Thread {
newJunction = t.nodes.get(0);
newTarget = t.nodes.get(1);
- setNewVoiceHint(t, last, lastJunctions, newJunction, newTarget);
+ tt.cost = tt.nodes.get(tt.nodes.size()-1).cost;
+ t.cost = t.nodes.get(t.nodes.size()-1).cost;
+
+ // fill to correctedpoint
+ startWp.correctedpoint = new OsmNode(newJunction.getILon(), newJunction.getILat());
return true;
}
return false;
}
- private void setNewVoiceHint(OsmTrack t, OsmPathElement last, CompactLongMap lastJunctiona, OsmPathElement newJunction, OsmPathElement newTarget) {
-
- if (last == null || newJunction == null || newTarget == null)
- return;
- int lon0,
- lat0,
- lon1,
- lat1,
- lon2,
- lat2;
- lon0 = last.getILon();
- lat0 = last.getILat();
- lon1 = newJunction.getILon();
- lat1 = newJunction.getILat();
- lon2 = newTarget.getILon();
- lat2 = newTarget.getILat();
- // get a new angle
- double angle = routingContext.anglemeter.calcAngle(lon0, lat0, lon1, lat1, lon2, lat2);
-
- newTarget.message.turnangle = (float) angle;
- }
-
private void recalcTrack(OsmTrack t) {
int totaldist = 0;
int totaltime = 0;
@@ -1553,7 +1795,7 @@ public class RoutingEngine extends Thread {
OsmPath p = getStartPath(n1, n2, new OsmNodeNamed(mwp.crosspoint), endPos, sameSegmentSearch);
// special case: start+end on same segment
- if (p.cost >= 0 && sameSegmentSearch && endPos != null && endPos.radius < 1.5) {
+ if (p != null && p.cost >= 0 && sameSegmentSearch && endPos != null && endPos.radius < 1.5) {
p.treedepth = 0; // hack: mark for the final-check
}
return p;
@@ -1592,7 +1834,7 @@ public class RoutingEngine extends Thread {
if (bestLink != null) {
bestLink.addLinkHolder(bestPath, n1);
}
- bestPath.treedepth = 1;
+ if (bestPath != null) bestPath.treedepth = 1;
return bestPath;
} finally {
@@ -1690,6 +1932,9 @@ public class RoutingEngine extends Thread {
logInfo("firstMatchCost from initial match=" + firstMatchCost);
}
+ if (startPath1 == null) return null;
+ if (startPath2 == null) return null;
+
synchronized (openSet) {
openSet.clear();
addToOpenset(startPath1);
diff --git a/brouter-core/src/main/java/btools/router/RoutingParamCollector.java b/brouter-core/src/main/java/btools/router/RoutingParamCollector.java
index f239315..1bcc6ee 100644
--- a/brouter-core/src/main/java/btools/router/RoutingParamCollector.java
+++ b/brouter-core/src/main/java/btools/router/RoutingParamCollector.java
@@ -227,6 +227,8 @@ public class RoutingParamCollector {
}
} else if (key.equals("exportWaypoints")) {
rctx.exportWaypoints = (Integer.parseInt(value) == 1);
+ } else if (key.equals("exportCorrectedWaypoints")) {
+ rctx.exportCorrectedWaypoints = (Integer.parseInt(value) == 1);
} else if (key.equals("format")) {
rctx.outputFormat = ((String) value).toLowerCase();
} else if (key.equals("trackFormat")) {
diff --git a/brouter-core/src/main/java/btools/router/VoiceHint.java b/brouter-core/src/main/java/btools/router/VoiceHint.java
index 691453c..09d38ca 100644
--- a/brouter-core/src/main/java/btools/router/VoiceHint.java
+++ b/brouter-core/src/main/java/btools/router/VoiceHint.java
@@ -580,7 +580,11 @@ public class VoiceHint {
} else if (lowerBadWayAngle >= -100.f && higherBadWayAngle < 45.f) {
cmd = KL;
} else {
- cmd = C;
+ if (lowerBadWayAngle > -35.f && higherBadWayAngle > 55.f) {
+ cmd = KR;
+ } else {
+ cmd = C;
+ }
}
} else if (cmdAngle < 5.f) {
if (lowerBadWayAngle > -30.f) {
@@ -597,7 +601,11 @@ public class VoiceHint {
} else if (lowerBadWayAngle > -45.f && higherBadWayAngle <= 100.f) {
cmd = KR;
} else {
- cmd = C;
+ if (lowerBadWayAngle < -55.f && higherBadWayAngle < 35.f) {
+ cmd = KL;
+ } else {
+ cmd = C;
+ }
}
} else if (cmdAngle < 45.f) {
cmd = TSLR;
diff --git a/brouter-core/src/main/java/btools/router/VoiceHintProcessor.java b/brouter-core/src/main/java/btools/router/VoiceHintProcessor.java
index 5df8a67..83a2ad4 100644
--- a/brouter-core/src/main/java/btools/router/VoiceHintProcessor.java
+++ b/brouter-core/src/main/java/btools/router/VoiceHintProcessor.java
@@ -116,6 +116,7 @@ public final class VoiceHintProcessor {
input.angle = roundAboutTurnAngle;
input.goodWay.turnangle = roundAboutTurnAngle;
input.distanceToNext = distance;
+ input.turnAngleConsumed = true;
//input.roundaboutExit = startTurn < 0 ? roundaboutExit : -roundaboutExit;
input.roundaboutExit = roundAboutTurnAngle < 0 ? roundaboutExit : -roundaboutExit;
float tmpangle = 0;
@@ -314,7 +315,13 @@ public final class VoiceHintProcessor {
input.cmd == VoiceHint.KR ||
input.cmd == VoiceHint.KL)
&& !input.goodWay.isLinktType()) {
- if (input.goodWay.getPrio() < input.maxBadPrio && (inputLastSaved != null && inputLastSaved.distanceToNext > catchingRange)) {
+ if (
+ ((Math.abs(input.lowerBadWayAngle) < 35.f ||
+ input.higherBadWayAngle < 35.f)
+ || input.goodWay.getPrio() < input.maxBadPrio)
+ && (inputLastSaved != null && inputLastSaved.distanceToNext > minRange)
+ && (input.distanceToNext > minRange)
+ ) {
results.add(input);
} else {
if (inputLast != null) { // when drop add distance to last
diff --git a/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java b/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java
index 630af03..e94677e 100644
--- a/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java
+++ b/brouter-expressions/src/main/java/btools/expressions/BExpressionContext.java
@@ -782,7 +782,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier {
public void parseFile(File file, String readOnlyContext, Map keyValues) {
if (!file.exists()) {
- throw new IllegalArgumentException("profile " + file + " does not exist");
+ throw new IllegalArgumentException("profile " + file.getName() + " does not exist");
}
try {
if (readOnlyContext != null) {
@@ -813,12 +813,12 @@ public abstract class BExpressionContext implements IByteArrayUnifier {
variableData[i] = readOnlyData[i];
}
} catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("ParseException " + file + " at line " + linenr + ": " + e.getMessage());
+ throw new IllegalArgumentException("ParseException " + file.getName() + " at line " + linenr + ": " + e.getMessage());
} catch (Exception e) {
throw new RuntimeException(e);
}
if (expressionList.size() == 0) {
- throw new IllegalArgumentException(file.getAbsolutePath()
+ throw new IllegalArgumentException(file.getName()
+ " does not contain expressions for context " + context + " (old version?)");
}
}
diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/MatchedWaypoint.java b/brouter-mapaccess/src/main/java/btools/mapaccess/MatchedWaypoint.java
index c9556d5..4c2a415 100644
--- a/brouter-mapaccess/src/main/java/btools/mapaccess/MatchedWaypoint.java
+++ b/brouter-mapaccess/src/main/java/btools/mapaccess/MatchedWaypoint.java
@@ -16,6 +16,7 @@ public final class MatchedWaypoint {
public OsmNode node2;
public OsmNode crosspoint;
public OsmNode waypoint;
+ public OsmNode correctedpoint;
public String name; // waypoint name used in error messages
public double radius; // distance in meter between waypoint and crosspoint
public boolean direct; // from this point go direct to next = beeline routing
diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java
index 6096c79..b2769cd 100644
--- a/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java
+++ b/brouter-mapaccess/src/main/java/btools/mapaccess/WaypointMatcherImpl.java
@@ -116,7 +116,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher {
double r22 = x2 * x2 + y2 * y2;
double radius = Math.abs(r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy) / d;
- if (radius < mwp.radius) {
+ if (radius <= mwp.radius) {
double s1 = x1 * dx + y1 * dy;
double s2 = x2 * dx + y2 * dy;
diff --git a/brouter-routing-app/build.gradle b/brouter-routing-app/build.gradle
index d6a9bfc..beec651 100644
--- a/brouter-routing-app/build.gradle
+++ b/brouter-routing-app/build.gradle
@@ -8,7 +8,7 @@ plugins {
}
android {
- compileSdk 35
+ compileSdk 36
base {
archivesName = "BRouterApp." + project.version
@@ -18,13 +18,13 @@ android {
namespace 'btools.routingapp'
applicationId "btools.routingapp"
- versionCode 54
+ versionCode 55
versionName project.version
resValue('string', 'app_version', defaultConfig.versionName)
minSdkVersion 21
- targetSdkVersion 34
+ targetSdkVersion 36
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -100,9 +100,9 @@ repositories {
}
dependencies {
- implementation 'androidx.appcompat:appcompat:1.7.0'
- implementation "androidx.constraintlayout:constraintlayout:2.1.4"
- implementation 'androidx.work:work-runtime:2.9.0'
+ implementation 'androidx.appcompat:appcompat:1.7.1'
+ implementation "androidx.constraintlayout:constraintlayout:2.2.1"
+ implementation 'androidx.work:work-runtime:2.10.2'
implementation 'com.google.android.material:material:1.12.0'
implementation project(':brouter-mapaccess')
@@ -115,7 +115,7 @@ dependencies {
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
- androidTestImplementation 'androidx.work:work-testing:2.9.0'
+ androidTestImplementation 'androidx.work:work-testing:2.10.2'
}
gradle.projectsEvaluated {
diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java
index 485d03f..dc1c0a1 100644
--- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java
+++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterView.java
@@ -30,6 +30,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.zip.ZipEntry;
@@ -44,6 +45,8 @@ import btools.router.OsmTrack;
import btools.router.RoutingContext;
import btools.router.RoutingEngine;
import btools.router.RoutingHelper;
+import btools.router.RoutingParamCollector;
+
import btools.util.CheapRuler;
public class BRouterView extends View {
@@ -437,6 +440,7 @@ public class BRouterView extends View {
public void startProcessing(String profile) {
rawTrackPath = null;
+ String params = null;
if (profile.startsWith(" 2) {
+ try {
+ Map profileParamsCollection = null;
+ RoutingParamCollector routingParamCollector = new RoutingParamCollector();
+ profileParamsCollection = routingParamCollector.getUrlParams(params);
+ routingParamCollector.setProfileParams(rc, profileParamsCollection);
+ } catch (Exception e) {}
+ }
+
int plain_distance = 0;
int maxlon = Integer.MIN_VALUE;
int minlon = Integer.MAX_VALUE;
diff --git a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java
index 33ee802..093b9f6 100644
--- a/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java
+++ b/brouter-routing-app/src/main/java/btools/routingapp/BRouterWorker.java
@@ -100,11 +100,19 @@ public class BRouterWorker {
}
routingParamCollector.setParams(rc, waypoints, theParams);
+ Map profileParamsCollection = null;
+ try {
+ if (profileParams != null) {
+ profileParamsCollection = routingParamCollector.getUrlParams(profileParams);
+ routingParamCollector.setProfileParams(rc, profileParamsCollection);
+ }
+ } catch (UnsupportedEncodingException e) {
+ // ignore
+ }
if (params.containsKey("extraParams")) {
- Map profileparams = null;
try {
- profileparams = routingParamCollector.getUrlParams(params.getString("extraParams"));
- routingParamCollector.setProfileParams(rc, profileparams);
+ profileParamsCollection = routingParamCollector.getUrlParams(params.getString("extraParams"));
+ routingParamCollector.setProfileParams(rc, profileParamsCollection);
} catch (UnsupportedEncodingException e) {
// ignore
}
@@ -161,6 +169,7 @@ public class BRouterWorker {
track = cr.getFoundTrack();
if (track != null) {
track.exportWaypoints = rc.exportWaypoints;
+ track.exportCorrectedWaypoints = rc.exportCorrectedWaypoints;
if (pathToFileResult == null) {
switch (writeFromat) {
case OUTPUT_FORMAT_KML:
@@ -212,6 +221,14 @@ public class BRouterWorker {
bw.write("\n");
writeWPList(bw, waypoints);
writeWPList(bw, rc.nogopoints);
+ if (rc.keyValues != null) {
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry e : rc.keyValues.entrySet()) {
+ sb.append(sb.length()>0 ? "&" : "").append(e.getKey()).append("=").append(e.getValue());
+ }
+ bw.write(sb.toString());
+ bw.write("\n");
+ }
bw.close();
}
diff --git a/brouter-routing-app/src/main/java/btools/routingapp/RoutingParameterDialog.java b/brouter-routing-app/src/main/java/btools/routingapp/RoutingParameterDialog.java
index d69a037..3557b55 100644
--- a/brouter-routing-app/src/main/java/btools/routingapp/RoutingParameterDialog.java
+++ b/brouter-routing-app/src/main/java/btools/routingapp/RoutingParameterDialog.java
@@ -377,8 +377,8 @@ public class RoutingParameterDialog extends AppCompatActivity {
for (String tmp : sa) {
// Add the name and address to the ListPreference enties and entyValues
//L.v("AFTrack", "device: "+device.getName() + " -- " + device.getAddress());
- entryValues[i] = "" + i;
entries[i] = tmp.trim();
+ entryValues[i] = entries[i].split("=")[0].trim();
if (entryValues[i].equals(s)) ii = i;
i++;
}
@@ -394,11 +394,14 @@ public class RoutingParameterDialog extends AppCompatActivity {
listPref.setSummary(p.description);
listPref.setOnPreferenceChangeListener((Preference preference, Object newValue) -> {
p.value = (String) newValue;
- int iii = Integer.decode(p.value);
- listPref.setTitle(p.name + ": " + entries[iii]);
-
+ for (int iii = 0; iii < entryValues.length; iii++) {
+ String entryValue = entryValues[iii];
+ if (entryValue.equals(p.value)) {
+ listPref.setTitle(p.name + ": " + entries[iii]);
+ break;
+ }
+ }
return true;
-
});
gpsPrefCat.addPreference(listPref);
diff --git a/brouter-server/src/main/java/btools/server/RouteServer.java b/brouter-server/src/main/java/btools/server/RouteServer.java
index 4b2be7a..2def82b 100644
--- a/brouter-server/src/main/java/btools/server/RouteServer.java
+++ b/brouter-server/src/main/java/btools/server/RouteServer.java
@@ -160,8 +160,8 @@ public class RouteServer extends Thread implements Comparable {
} else if (url.startsWith(PROFILE_UPLOAD_URL)) {
if (getline.startsWith("OPTIONS")) {
// handle CORS preflight request (Safari)
- String corsHeaders = "Access-Control-Allow-Methods: GET, POST\n"
- + "Access-Control-Allow-Headers: Content-Type\n";
+ String corsHeaders = "Access-Control-Allow-Methods: GET, POST\r\n"
+ + "Access-Control-Allow-Headers: Content-Type\r\n";
writeHttpHeader(bw, "text/plain", null, corsHeaders, HTTP_STATUS_OK);
bw.flush();
return;
@@ -220,7 +220,7 @@ public class RouteServer extends Thread implements Comparable {
// no zip for this engineMode
encodings = null;
}
- String headers = encodings == null || encodings.indexOf("gzip") < 0 ? null : "Content-Encoding: gzip\n";
+ String headers = encodings == null || encodings.indexOf("gzip") < 0 ? null : "Content-Encoding: gzip\r\n";
writeHttpHeader(bw, handler.getMimeType(), handler.getFileName(), headers, HTTP_STATUS_OK);
if (engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUTING ||
engineMode == RoutingEngine.BROUTER_ENGINEMODE_ROUNDTRIP) {
@@ -407,17 +407,17 @@ public class RouteServer extends Thread implements Comparable {
private static void writeHttpHeader(BufferedWriter bw, String mimeType, String fileName, String headers, String status) throws IOException {
// http-header
- bw.write(String.format("HTTP/1.1 %s\n", status));
- bw.write("Connection: close\n");
- bw.write("Content-Type: " + mimeType + "; charset=utf-8\n");
+ bw.write(String.format("HTTP/1.1 %s\r\n", status));
+ bw.write("Connection: close\r\n");
+ bw.write("Content-Type: " + mimeType + "; charset=utf-8\r\n");
if (fileName != null) {
- bw.write("Content-Disposition: attachment; filename=\"" + fileName + "\"\n");
+ bw.write("Content-Disposition: attachment; filename=\"" + fileName + "\"\r\n");
}
- bw.write("Access-Control-Allow-Origin: *\n");
+ bw.write("Access-Control-Allow-Origin: *\r\n");
if (headers != null) {
bw.write(headers);
}
- bw.write("\n");
+ bw.write("\r\n");
}
private static void cleanupThreadQueue(Queue threadQueue) {
diff --git a/brouter-server/src/main/java/btools/server/request/ServerHandler.java b/brouter-server/src/main/java/btools/server/request/ServerHandler.java
index 37ba145..fcb536c 100644
--- a/brouter-server/src/main/java/btools/server/request/ServerHandler.java
+++ b/brouter-server/src/main/java/btools/server/request/ServerHandler.java
@@ -78,6 +78,10 @@ public class ServerHandler extends RequestHandler {
if (exportWaypointsStr != null && Integer.parseInt(exportWaypointsStr) != 0) {
track.exportWaypoints = true;
}
+ exportWaypointsStr = params.get("exportCorrectedWaypoints");
+ if (exportWaypointsStr != null && Integer.parseInt(exportWaypointsStr) != 0) {
+ track.exportCorrectedWaypoints = true;
+ }
if (format == null || "gpx".equals(format)) {
result = new FormatGpx(rc).format(track);
diff --git a/brouter-server/src/test/java/btools/server/RouteServerTest.java b/brouter-server/src/test/java/btools/server/RouteServerTest.java
index d4c971e..ad6776c 100644
--- a/brouter-server/src/test/java/btools/server/RouteServerTest.java
+++ b/brouter-server/src/test/java/btools/server/RouteServerTest.java
@@ -14,6 +14,8 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -28,7 +30,7 @@ public class RouteServerTest {
public static TemporaryFolder profileDir = new TemporaryFolder();
@BeforeClass
- public static void setupServer() throws IOException, InterruptedException {
+ public static void setupServer() throws IOException, InterruptedException, URISyntaxException {
File workingDir = new File(".").getCanonicalFile();
File segmentDir = new File(workingDir, "../brouter-map-creator/build/resources/test/tmp/segments");
File profileSourceDir = new File(workingDir, "../misc/profiles2");
@@ -41,7 +43,7 @@ public class RouteServerTest {
try {
RouteServer.main(new String[]{segmentDir.getAbsolutePath(), profileDir.getRoot().getAbsolutePath(), customProfileDir, port, "1"});
} catch (Exception e) {
- e.printStackTrace();
+ e.printStackTrace(System.out);
}
};
@@ -49,7 +51,7 @@ public class RouteServerTest {
thread.start();
// Busy-wait for server startup
- URL requestUrl = new URL(baseUrl);
+ URL requestUrl = new URI(baseUrl).toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
for (int i = 20; i >= 0; i--) {
try {
@@ -66,8 +68,8 @@ public class RouteServerTest {
}
@Test
- public void defaultRouteTrekking() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.723037,50.000491|8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson");
+ public void defaultRouteTrekking() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.723037,50.000491%7C8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
@@ -82,8 +84,8 @@ public class RouteServerTest {
}
@Test
- public void overrideParameter() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.723037,50.000491|8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson&profile:avoid_unsafe=1");
+ public void overrideParameter() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.723037,50.000491%7C8.712737,50.002899&nogos=&profile=trekking&alternativeidx=0&format=geojson&profile:avoid_unsafe=1").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
@@ -95,8 +97,8 @@ public class RouteServerTest {
}
@Test
- public void voiceHints() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.705796,50.003124|8.705859,50.0039599&nogos=&profile=trekking&alternativeidx=0&format=geojson&timode=2");
+ public void voiceHints() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.705796,50.003124%7C8.705859,50.0039599&nogos=&profile=trekking&alternativeidx=0&format=geojson&timode=2").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
@@ -108,8 +110,8 @@ public class RouteServerTest {
}
@Test
- public void directRoutingFirst() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.718354,50.001514|8.718917,50.001361|8.716986,50.000105|8.718306,50.00145&nogos=&profile=trekking&alternativeidx=0&format=geojson&straight=0&timode=3");
+ public void directRoutingFirst() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.718354,50.001514%7C8.718917,50.001361%7C8.716986,50.000105%7C8.718306,50.00145&nogos=&profile=trekking&alternativeidx=0&format=geojson&straight=0&timode=3").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
@@ -121,8 +123,8 @@ public class RouteServerTest {
}
@Test
- public void directRoutingLast() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.718306,50.00145|8.717464,50.000405|8.718917,50.001361|8.718354,50.001514&nogos=&profile=trekking&alternativeidx=0&format=geojson&straight=2&timode=3");
+ public void directRoutingLast() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.718306,50.00145%7C8.717464,50.000405%7C8.718917,50.001361%7C8.718354,50.001514&nogos=&profile=trekking&alternativeidx=0&format=geojson&straight=2&timode=3").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
@@ -134,8 +136,8 @@ public class RouteServerTest {
}
@Test
- public void directRoutingMiddle() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.718539,50.006581|8.718198,50.006065,d|8.71785,50.006034|8.7169,50.004456&nogos=&profile=trekking&alternativeidx=0&format=geojson&timode=3");
+ public void directRoutingMiddle() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.718539,50.006581%7C8.718198,50.006065,d%7C8.71785,50.006034%7C8.7169,50.004456&nogos=&profile=trekking&alternativeidx=0&format=geojson&timode=3").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
@@ -147,8 +149,8 @@ public class RouteServerTest {
}
@Test
- public void misplacedPoints() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter?lonlats=8.708678,49.999188|8.71145,49.999761|8.715801,50.00065&nogos=&profile=trekking&alternativeidx=0&format=geojson&correctMisplacedViaPoints=1&timode=3");
+ public void misplacedPoints() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.708678,49.999188%7C8.71145,49.999761%7C8.715801,50.00065&nogos=&profile=trekking&alternativeidx=0&format=geojson&correctMisplacedViaPoints=1&timode=3").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
@@ -160,8 +162,21 @@ public class RouteServerTest {
}
@Test
- public void uploadValidProfile() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter/profile");
+ public void misplacedPointsRoundabout() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter?lonlats=8.699487,50.001257%7C8.701569,50.000092%7C8.704873,49.998898&nogos=&profile=trekking&alternativeidx=0&format=geojson&profile:correctMisplacedViaPoints=1&timode=3").toURL();
+ HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
+ httpConnection.connect();
+
+ Assert.assertEquals(HttpURLConnection.HTTP_OK, httpConnection.getResponseCode());
+
+ InputStream inputStream = httpConnection.getInputStream();
+ JSONObject geoJson = new JSONObject(new String(inputStream.readAllBytes(), StandardCharsets.UTF_8));
+ Assert.assertEquals("482", geoJson.query("/features/0/properties/track-length"));
+ }
+
+ @Test
+ public void uploadValidProfile() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter/profile").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.setRequestMethod("POST");
@@ -192,8 +207,8 @@ public class RouteServerTest {
}
@Test
- public void uploadInvalidProfile() throws IOException {
- URL requestUrl = new URL(baseUrl + "brouter/profile");
+ public void uploadInvalidProfile() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "brouter/profile").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.setRequestMethod("POST");
@@ -214,8 +229,8 @@ public class RouteServerTest {
}
@Test
- public void robots() throws IOException {
- URL requestUrl = new URL(baseUrl + "robots.txt");
+ public void robots() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "robots.txt").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
@@ -226,8 +241,8 @@ public class RouteServerTest {
}
@Test
- public void invalidUrl() throws IOException {
- URL requestUrl = new URL(baseUrl + "invalid");
+ public void invalidUrl() throws IOException, URISyntaxException {
+ URL requestUrl = new URI(baseUrl + "invalid").toURL();
HttpURLConnection httpConnection = (HttpURLConnection) requestUrl.openConnection();
httpConnection.connect();
diff --git a/brouter-util/src/main/java/btools/util/StackSampler.java b/brouter-util/src/main/java/btools/util/StackSampler.java
index 753fec4..53c5db6 100644
--- a/brouter-util/src/main/java/btools/util/StackSampler.java
+++ b/brouter-util/src/main/java/btools/util/StackSampler.java
@@ -12,7 +12,7 @@ import java.util.Map;
import java.util.Random;
public class StackSampler extends Thread {
- private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS", new Locale("en", "US"));
+ private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS", new Locale.Builder().setLanguage("en").setRegion("US").build());
private BufferedWriter bw;
private Random rand = new Random();
diff --git a/build.gradle b/build.gradle
index 946559c..6fd211e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,13 +6,13 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.7.3'
+ classpath 'com.android.tools.build:gradle:8.10.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
-task clean(type: Delete) {
- delete rootProject.buildDir
+tasks.register('clean', Delete) {
+ delete rootProject.layout.buildDirectory
}
diff --git a/buildSrc/src/main/groovy/brouter.version-conventions.gradle b/buildSrc/src/main/groovy/brouter.version-conventions.gradle
index b99c641..e0ce18b 100644
--- a/buildSrc/src/main/groovy/brouter.version-conventions.gradle
+++ b/buildSrc/src/main/groovy/brouter.version-conventions.gradle
@@ -4,4 +4,4 @@
// app: build.gradle (versionCode only)
// OsmTrack (version and versionDate)
// docs revisions.md (version and versionDate)
-version '1.7.7'
+version '1.7.8'
diff --git a/docs/revisions.md b/docs/revisions.md
index 895d4d5..c9a492b 100644
--- a/docs/revisions.md
+++ b/docs/revisions.md
@@ -2,7 +2,7 @@
(ZIP-Archives including APK, readme + profiles)
-### next version
+### [brouter-1.7.8.zip](../brouter_bin/brouter-1.7.8.zip) (current revision, 12.07.2025)
Android
@@ -10,6 +10,8 @@ Android
- use parameter changed in the BRouter app
- reuse parameter for repeat:profile function
- use unordered values for profile listbox (e.g. fastbike profile)
+- Android 16
+
Library
@@ -26,7 +28,7 @@ Library
[Solved issues](https://github.com/abrensch/brouter/issues?q=is%3Aissue+milestone%3A%22Version+1.7.8%22+is%3Aclosed)
-### [brouter-1.7.7.zip](../brouter_bin/brouter-1.7.7.zip) (current revision, 23.07.2024)
+### [brouter-1.7.7.zip](../brouter_bin/brouter-1.7.7.zip) (23.07.2024)
- new Android API 34
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e644113..9bbc975 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 09523c0..37f853b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index 1aa94a4..faf9300 100755
--- a/gradlew
+++ b/gradlew
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# SPDX-License-Identifier: Apache-2.0
+#
##############################################################################
#
@@ -55,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -84,7 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -203,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
diff --git a/gradlew.bat b/gradlew.bat
index 7101f8e..9b42019 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,6 +13,8 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
diff --git a/misc/profiles2/.gitignore b/misc/profiles2/.gitignore
index 8e365df..751a83b 100644
--- a/misc/profiles2/.gitignore
+++ b/misc/profiles2/.gitignore
@@ -2,7 +2,7 @@
/car-fast.brf
/fastbike-asia-pacific.brf
/fastbike-lowtraffic.brf
-/safety.brf
+#/safety.brf
/trekking-ignore-cr.brf
/trekking-noferries.brf
/trekking-nosteps.brf
diff --git a/misc/profiles2/fastbike.brf b/misc/profiles2/fastbike.brf
index 97006bb..4507cc3 100644
--- a/misc/profiles2/fastbike.brf
+++ b/misc/profiles2/fastbike.brf
@@ -23,7 +23,7 @@ assign allow_steps = true # %allow_steps% | Set to false to disallow
assign allow_ferries = true # %allow_ferries% | set to false to disallow ferries | boolean
assign allow_motorways = false # %allow_motorways% | Set to true to allow motorways (useful in Asia / Oceania for example) | boolean
-assign consider_traffic = false # %consider_traffic% | Activate to avoid traffic | boolean
+assign consider_traffic = 1 # %consider_traffic% | how do you plan to drive the tour? | [1=as cyclist alone in the week, 0.5=as cyclist alone at weekend, 0.3 =with a group of cyclists, 0.1=with a group of cyclists at week-end, 0.0=do not consider traffic]
assign consider_noise = false # %consider_noise% | Activate to prefer a low-noise route | boolean
assign consider_river = false # %consider_river% | Activate to prefer a route along rivers, lakes, etc. | boolean
assign consider_forest = false # %consider_forest% | Activate to prefer a route in forest or parks | boolean
@@ -154,43 +154,14 @@ assign onewaypenalty =
assign hascycleway = not
and ( or cycleway= cycleway=no|none ) and ( or cycleway:left= cycleway:left=no ) ( or cycleway:right= cycleway:right=no )
-assign trafficpenalty0 =
- if consider_traffic then
- (
- if highway=primary|primary_link then
- (
- if estimated_traffic_class=4 then 0.2
- else if estimated_traffic_class=5 then 0.4
- else if estimated_traffic_class=6|7 then 0.6
- else 0
- )
- else if highway=secondary|secondary_link then
- (
- if estimated_traffic_class=3 then 0.2
- else if estimated_traffic_class=4 then 0.4
- else if estimated_traffic_class=5 then 0.6
- else if estimated_traffic_class=6|7 then 1
- else 0
- )
- else if highway=tertiary|tertiary_link then
- (
- if estimated_traffic_class=2 then 0.1
- else if estimated_traffic_class=3 then 0.3
- else if estimated_traffic_class=4 then 0.5
- else if estimated_traffic_class=5|6|7 then 1
- else 0
- )
- else 0
- )
- else 0
assign trafficpenalty =
- if consider_traffic then
- (
- if hascycleway then min 0.3 trafficpenalty0
- else trafficpenalty0
- )
- else 0
+ if estimated_traffic_class=|1|2 then 0
+ else if estimated_traffic_class=3 then multiply 0.3 consider_traffic
+ else if estimated_traffic_class=4 then multiply 0.6 consider_traffic
+ else if estimated_traffic_class=5 then multiply 0.9 consider_traffic
+ else if estimated_traffic_class=6|7 then multiply 1.5 consider_traffic
+ else 0
assign isresidentialorliving = or highway=residential|living_street living_street=yes
diff --git a/misc/profiles2/hiking-mountain.brf b/misc/profiles2/hiking-mountain.brf
index 6d3d920..2b36b81 100644
--- a/misc/profiles2/hiking-mountain.brf
+++ b/misc/profiles2/hiking-mountain.brf
@@ -15,7 +15,6 @@ assign consider_noise = false # %consider_noise% | Activate to prefe
assign consider_river = false # %consider_river% | Activate to prefer a route along rivers, lakes, etc. | boolean
assign consider_forest = false # %consider_forest% | Activate to prefer a route in forest or green areas| boolean
assign consider_town = false # %consider_town% | Activate to bypass cities / big towns as far as possible | boolean
-assign consider_traffic = 1 # %consider_traffic% | how do you plan to drive the tour? | [1=as cyclist alone in the week, 0.5=as cyclist alone at weekend, 0.3 =with a group of cyclists, 0.1=with a group of cyclists at week-end]
assign shortest_way 0 # 0 as default, duplicate shortest standard profile, SAC access limit ignored for now
@@ -359,36 +358,7 @@ assign town_penalty
switch estimated_town_class=5 1.4
switch estimated_town_class=6 1.6 99 0
-assign trafficpenalty =
-# if any_cycleway then 0
-# else
-if highway=primary|primary_link then
- (
- if estimated_traffic_class=1|2 then 0
- else if estimated_traffic_class=3 then multiply 0.4 consider_traffic
- else if estimated_traffic_class=4 then multiply 0.8 consider_traffic
- else if estimated_traffic_class=5 then multiply 1 consider_traffic
- else if estimated_traffic_class=6|7 then multiply 2 consider_traffic
- else multiply 0.6 consider_traffic
- )
- else if highway=secondary|secondary_link then
- (
- if estimated_traffic_class=1|2 then multiply 0.1 consider_traffic
- else if estimated_traffic_class=3 then multiply 0.3 consider_traffic
- else if estimated_traffic_class=4 then multiply 0.7 consider_traffic
- else if estimated_traffic_class=5 then multiply 1 consider_traffic
- else if estimated_traffic_class=6|7 then multiply 1.5 consider_traffic
- else multiply 0.2 consider_traffic
- )
- else if highway=tertiary|tertiary_link then
- (
- if estimated_traffic_class=1|2 then multiply 0.1 consider_traffic
- else if estimated_traffic_class=3 then multiply 0.2 consider_traffic
- else if estimated_traffic_class=4 then multiply 0.5 consider_traffic
- else multiply if estimated_traffic_class=5|6|7 then multiply 1 consider_traffic
- else 0.1 consider_traffic
- )
- else 0
+assign trafficpenalty = 0
assign costfactor
add town_penalty
diff --git a/misc/profiles2/lookups.dat b/misc/profiles2/lookups.dat
index e8dafc1..d51f455 100644
--- a/misc/profiles2/lookups.dat
+++ b/misc/profiles2/lookups.dat
@@ -711,6 +711,11 @@ estimated_town_class;0000000001 4
estimated_town_class;0000000001 5
estimated_town_class;0000000001 6
+lts_score;2000000001 1
+lts_score;2000000002 2
+lts_score;2000000003 3
+lts_score;2000000004 4
+
---context:node
diff --git a/misc/profiles2/safety.brf b/misc/profiles2/safety.brf
new file mode 100644
index 0000000..8a6345d
--- /dev/null
+++ b/misc/profiles2/safety.brf
@@ -0,0 +1,403 @@
+# *** The trekking profile is for slow travel
+# *** and avoiding car traffic, but still with
+# *** a focus on approaching your destination
+# *** efficiently.
+
+---context:global # following code refers to global config
+
+# Bike profile
+assign validForBikes = true
+
+# Use the following switches to change behaviour
+assign allow_steps = true # %allow_steps% | Set false to disallow steps | boolean
+assign allow_ferries = true # %allow_ferries% | Set false to disallow ferries | boolean
+assign ignore_cycleroutes = false # %ignore_cycleroutes% | Set true for better elevation results | boolean
+assign stick_to_cycleroutes = false # %stick_to_cycleroutes% | Set true to just follow cycleroutes | boolean
+assign avoid_unsafe = true # %avoid_unsafe% | Set true to avoid standard highways | boolean
+
+assign add_beeline = false # %add_beeline% | Enable beeline on distant start/end points | boolean
+
+assign consider_noise = false # %consider_noise% | Activate to prefer a low-noise route | boolean
+assign consider_river = false # %consider_river% | Activate to prefer a route along rivers, lakes, etc. | boolean
+assign consider_forest = false # %consider_forest% | Activate to prefer a route in forest or parks | boolean
+assign consider_town = false # %consider_town% | Activate to bypass cities / big towns as far as possible | boolean
+assign consider_traffic = false # %consider_traffic% | Activate to consider traffic estimates | boolean
+
+
+
+# Change elevation parameters
+assign consider_elevation = true # %consider_elevation% | Set true to favor a route with few elevation meters | boolean
+
+assign downhillcost = 60 # %downhillcost% | Cost for going downhill | number
+assign downhillcutoff = 1.5 # %downhillcutoff% | Gradients below this value in percents are not counted. | number
+assign uphillcost = 0 # %uphillcost% | Cost for going uphill | number
+assign uphillcutoff = 1.5 # %uphillcutoff% | Gradients below this value in percents are not counted. | number
+
+assign downhillcost = if consider_elevation then downhillcost else 0
+assign uphillcost = if consider_elevation then uphillcost else 0
+
+# Kinematic model parameters (travel time computation)
+assign totalMass = 90 # %totalMass% | Mass (in kg) of the bike + biker, for travel time computation | number
+assign maxSpeed = 45 # %maxSpeed% | Absolute maximum speed (in km/h), for travel time computation | number
+assign S_C_x = 0.225 # %S_C_x% | Drag coefficient times the reference area (in m^2), for travel time computation | number
+assign C_r = 0.01 # %C_r% | Rolling resistance coefficient (dimensionless), for travel time computation | number
+assign bikerPower = 100 # %bikerPower% | Average power (in W) provided by the biker, for travel time computation | number
+
+# Turn instructions settings
+assign turnInstructionMode = 1 # %turnInstructionMode% | Mode for the generated turn instructions | [0=none, 1=auto-choose, 2=locus-style, 3=osmand-style, 4=comment-style, 5=gpsies-style, 6=orux-style, 7=locus-old-style]
+assign turnInstructionCatchingRange = 40 # %turnInstructionCatchingRange% | Within this distance (in m) several turning instructions are combined into one and the turning angles are better approximated to the general direction | number
+assign turnInstructionRoundabouts = true # %turnInstructionRoundabouts% | Set "false" to avoid generating special turning instructions for roundabouts | boolean
+assign considerTurnRestrictions = true # %considerTurnRestrictions% | Set true to take turn restrictions into account | boolean
+
+assign processUnusedTags = true # %processUnusedTags% | Set true to output unused tags in data tab | boolean
+
+---context:way # following code refers to way-tags
+
+# classifier constants
+assign classifier_none = 1
+assign classifier_ferry = 2
+
+#
+# pre-calculate some logical expressions
+#
+
+assign any_cycleroute =
+ if route_bicycle_icn=yes then true
+ else if route_bicycle_ncn=yes then true
+ else if route_bicycle_rcn=yes then true
+ else if route_bicycle_lcn=yes then true
+ else false
+
+assign nodeaccessgranted =
+ if any_cycleroute then true
+ else lcn=yes
+
+assign is_ldcr =
+ if ignore_cycleroutes then false
+ else any_cycleroute
+
+assign isbike = or bicycle_road=yes or bicycle=yes or or bicycle=permissive bicycle=designated lcn=yes
+assign ispaved = surface=paved|asphalt|concrete|paving_stones|sett
+assign isunpaved = not or surface= or ispaved surface=fine_gravel|cobblestone
+assign probablyGood = or ispaved and ( or isbike highway=footway ) not isunpaved
+
+
+#
+# this is the cost (in Meter) for a 90-degree turn
+# The actual cost is calculated as turncost*cos(angle)
+# (Suppressing turncost while following longdistance-cycleways
+# makes them a little bit more magnetic)
+#
+assign turncost = if is_ldcr then 0
+ else if junction=roundabout then 0
+ else 90
+
+
+#
+# for any change in initialclassifier, initialcost is added once
+#
+assign initialclassifier =
+ if route=ferry then classifier_ferry
+ else classifier_none
+
+
+#
+# calculate the initial cost
+# this is added to the total cost each time the costfactor
+# changed
+#
+assign initialcost =
+ if ( equal initialclassifier classifier_ferry ) then 10000
+ else 0
+
+#
+# implicit access here just from the motorroad tag
+# (implicit access rules from highway tag handled elsewhere)
+#
+assign defaultaccess =
+ if access= then not motorroad=yes
+ else if access=private|no then false
+ else true
+
+#
+# calculate logical bike access
+#
+assign bikeaccess =
+ if bicycle= then
+ (
+ if bicycle_road=yes then true
+ else if vehicle= then ( if highway=footway then false else defaultaccess )
+ else not vehicle=private|no
+ )
+ else not bicycle=private|no|dismount|use_sidepath
+
+#
+# calculate logical foot access
+#
+assign footaccess =
+ if bicycle=dismount then true
+ else if foot= then defaultaccess
+ else not foot=private|no|use_sidepath
+
+#
+# if not bike-, but foot-acess, just a moderate penalty,
+# otherwise access is forbidden
+#
+assign accesspenalty =
+ if bikeaccess then 0
+ else if footaccess then 4
+ else if any_cycleroute then 15
+ else 10000
+
+#
+# handle one-ways. On primary roads, wrong-oneways should
+# be close to forbidden, while on other ways we just add
+# 4 to the costfactor (making it at least 5 - you are allowed
+# to push your bike)
+#
+assign badoneway =
+ if reversedirection=yes then
+ if oneway:bicycle=yes then true
+ else if oneway= then junction=roundabout
+ else oneway=yes|true|1
+ else oneway=-1
+
+assign onewaypenalty =
+ if ( badoneway ) then
+ (
+ if ( cycleway=opposite|opposite_lane|opposite_track ) then 0
+ else if ( cycleway:left=opposite|opposite_lane|opposite_track ) then 0
+ else if ( cycleway:right=opposite|opposite_lane|opposite_track ) then 0
+ else if ( oneway:bicycle=no ) then 0
+ else if ( cycleway:left:oneway=no ) then 0
+ else if ( cycleway:right:oneway=no ) then 0
+ else if ( not footaccess ) then 100
+ else if ( junction=roundabout|circular ) then 60
+ else if ( highway=primary|primary_link ) then 50
+ else if ( highway=secondary|secondary_link ) then 30
+ else if ( highway=tertiary|tertiary_link ) then 20
+ else 4.0
+ )
+ else 0.0
+
+# add estimate tags
+assign traffic_penalty
+ switch consider_traffic
+ switch estimated_traffic_class= 0
+ switch estimated_traffic_class=1|2 0.2
+ switch estimated_traffic_class=3 0.4
+ switch estimated_traffic_class=4 0.6
+ switch estimated_traffic_class=5 0.8
+ switch estimated_traffic_class=6|7 1 99 0
+
+
+assign noise_penalty
+ switch consider_noise
+ switch estimated_noise_class= 0
+ switch estimated_noise_class=1 0.3
+ switch estimated_noise_class=2 0.5
+ switch estimated_noise_class=3 0.8
+ switch estimated_noise_class=4 1.4
+ switch estimated_noise_class=5 1.7
+ switch estimated_noise_class=6 2 0 0
+
+assign no_river_penalty
+ switch consider_river
+ switch estimated_river_class= 2
+ switch estimated_river_class=1 1.3
+ switch estimated_river_class=2 1
+ switch estimated_river_class=3 0.7
+ switch estimated_river_class=4 0.4
+ switch estimated_river_class=5 0.1
+ switch estimated_river_class=6 0 99 0
+
+assign no_forest_penalty
+ switch consider_forest
+ switch estimated_forest_class= 1
+ switch estimated_forest_class=1 0.5
+ switch estimated_forest_class=2 0.4
+ switch estimated_forest_class=3 0.25
+ switch estimated_forest_class=4 0.15
+ switch estimated_forest_class=5 0.1
+ switch estimated_forest_class=6 0 99 0
+
+assign town_penalty
+ switch consider_town
+ switch estimated_town_class= 0
+ switch estimated_town_class=1 0.5
+ switch estimated_town_class=2 0.9
+ switch estimated_town_class=3 1.2
+ switch estimated_town_class=4 1.3
+ switch estimated_town_class=5 1.4
+ switch estimated_town_class=6 1.6 99 0
+
+#
+# calculate the cost-factor, which is the factor
+# by which the distance of a way-segment is multiplied
+# to calculate the cost of that segment. The costfactor
+# must be >=1 and it's supposed to be close to 1 for
+# the type of way the routing profile is searching for
+#
+assign isresidentialorliving = or highway=residential|living_street living_street=yes
+assign costfactor
+
+ #
+ # exclude rivers, rails etc.
+ #
+ if ( and highway= not route=ferry ) then 10000
+
+ #
+ # exclude motorways and proposed roads
+ #
+ else if ( highway=motorway|motorway_link ) then 10000
+ else if ( highway=proposed|abandoned ) then 10000
+
+ #
+ # all other exclusions below (access, steps, ferries,..)
+ # should not be deleted by the decoder, to be available
+ # in voice-hint-processing
+ #
+ else min 9999
+
+ add town_penalty
+ add no_forest_penalty
+ add no_river_penalty
+ add noise_penalty
+ add traffic_penalty
+
+ #
+ # apply oneway-and access-penalties
+ #
+ add max onewaypenalty accesspenalty
+
+ #
+ # steps and ferries are special. Note this is handled
+ # before the cycleroute-switch, to be able
+ # to really exclude them be setting cost to infinity
+ #
+ if ( highway=steps ) then ( if allow_steps then 40 else 10000 )
+ else if ( route=ferry ) then ( if allow_ferries then 5.67 else 10000 )
+
+ #
+ # handle long-distance cycle-routes.
+ #
+ else if ( is_ldcr ) then 1 # always treated as perfect (=1)
+ else
+ add ( if stick_to_cycleroutes then 0.5 else 0.05 ) # everything else somewhat up
+
+ #
+ # some other highway types
+ #
+ if ( highway=pedestrian ) then 3
+ else if ( highway=bridleway ) then 5
+ else if ( highway=cycleway ) then 1
+ else if ( isresidentialorliving ) then ( if isunpaved then 1.5 else 1.1 )
+ else if ( highway=service ) then ( if isunpaved then 1.6 else 1.3 )
+
+ #
+ # tracks and track-like ways are rated mainly be tracktype/grade
+ # But note that if no tracktype is given (mainly for road/path/footway)
+ # it can be o.k. if there's any other hint for quality
+ #
+ else if ( highway=track|road|path|footway ) then
+ (
+ if ( tracktype=grade1 ) then ( if probablyGood then 1.0 else 1.3 )
+ else if ( tracktype=grade2 ) then ( if probablyGood then 1.1 else 2.0 )
+ else if ( tracktype=grade3 ) then ( if probablyGood then 1.5 else 3.0 )
+ else if ( tracktype=grade4 ) then ( if probablyGood then 2.0 else 5.0 )
+ else if ( tracktype=grade5 ) then ( if probablyGood then 3.0 else 5.0 )
+ else ( if probablyGood then 1.0 else 5.0 )
+ )
+
+ #
+ # When avoiding unsafe ways, avoid highways without a bike hint
+ #
+ else add ( if ( and avoid_unsafe not isbike ) then 2 else 0 )
+
+ #
+ # actuals roads are o.k. if we have a bike hint
+ #
+ if ( highway=trunk|trunk_link ) then ( if isbike then 1.5 else 10 )
+ else if ( highway=primary|primary_link ) then ( if isbike then 1.2 else 3 )
+ else if ( highway=secondary|secondary_link ) then ( if isbike then 1.1 else 1.6 )
+ else if ( highway=tertiary|tertiary_link ) then ( if isbike then 1.0 else 1.4 )
+ else if ( highway=unclassified ) then ( if isbike then 1.0 else 1.3 )
+
+ #
+ # default for any other highway type not handled above
+ #
+ else 2.0
+
+
+# way priorities used for voice hint generation
+
+assign priorityclassifier =
+
+ if ( highway=motorway ) then 30
+ else if ( highway=motorway_link ) then 29
+ else if ( highway=trunk ) then 28
+ else if ( highway=trunk_link ) then 27
+ else if ( highway=primary ) then 26
+ else if ( highway=primary_link ) then 25
+ else if ( highway=secondary ) then 24
+ else if ( highway=secondary_link ) then 23
+ else if ( highway=tertiary ) then 22
+ else if ( highway=tertiary_link ) then 21
+ else if ( highway=unclassified ) then 20
+ else if ( isresidentialorliving ) then 6
+ else if ( highway=service ) then 6
+ else if ( highway=cycleway ) then 6
+ else if ( or bicycle=designated bicycle_road=yes ) then 6
+ else if ( highway=track ) then if tracktype=grade1 then 6 else 4
+ else if ( highway=bridleway|road|path|footway ) then 4
+ else if ( highway=steps ) then 2
+ else if ( highway=pedestrian ) then 2
+ else 0
+
+# some more classifying bits used for voice hint generation...
+
+assign isbadoneway = not equal onewaypenalty 0
+assign isgoodoneway = if reversedirection=yes then oneway=-1
+ else if oneway= then junction=roundabout else oneway=yes|true|1
+assign isroundabout = junction=roundabout
+assign islinktype = highway=motorway_link|trunk_link|primary_link|secondary_link|tertiary_link
+assign isgoodforcars = if greater priorityclassifier 6 then true
+ else if ( or isresidentialorliving highway=service ) then true
+ else if ( and highway=track tracktype=grade1 ) then true
+ else false
+
+# ... encoded into a bitmask
+
+assign classifiermask add isbadoneway
+ add multiply isgoodoneway 2
+ add multiply isroundabout 4
+ add multiply islinktype 8
+ multiply isgoodforcars 16
+
+# include `smoothness=` tags in the response's WayTags for track analysis
+assign dummyUsage = smoothness=
+
+---context:node # following code refers to node tags
+
+assign defaultaccess =
+ if ( access= ) then true # add default barrier restrictions here!
+ else if ( access=private|no ) then false
+ else true
+
+assign bikeaccess =
+ if nodeaccessgranted=yes then true
+ else if bicycle= then
+ (
+ if vehicle= then defaultaccess
+ else not vehicle=private|no
+ )
+ else not bicycle=private|no|dismount
+
+assign footaccess =
+ if bicycle=dismount then true
+ else if foot= then defaultaccess
+ else not foot=private|no
+
+assign initialcost =
+ if bikeaccess then 0
+ else ( if footaccess then 100 else 1000000 )
diff --git a/misc/profiles2/shortest.brf b/misc/profiles2/shortest.brf
index f4e66db..cd1034e 100644
--- a/misc/profiles2/shortest.brf
+++ b/misc/profiles2/shortest.brf
@@ -12,6 +12,9 @@ assign validForFoot 1
---context:way # following code refers to way-tags
+# show unused tags
+assign processUnusedTags = true
+
assign any_cycleroute or route_bicycle_icn=yes or route_bicycle_ncn=yes or route_bicycle_rcn=yes route_bicycle_lcn=yes
assign nodeaccessgranted or any_cycleroute lcn=yes
diff --git a/misc/profiles2/trekking.brf b/misc/profiles2/trekking.brf
index bc10708..231a939 100644
--- a/misc/profiles2/trekking.brf
+++ b/misc/profiles2/trekking.brf
@@ -49,7 +49,7 @@ assign turnInstructionCatchingRange = 40 # %turnInstructionCatchingRange% | W
assign turnInstructionRoundabouts = true # %turnInstructionRoundabouts% | Set "false" to avoid generating special turning instructions for roundabouts | boolean
assign considerTurnRestrictions = true # %considerTurnRestrictions% | Set true to take turn restrictions into account | boolean
-assign processUnusedTags = false # %processUnusedTags% | Set true to output unused tags in data tab | boolean
+assign processUnusedTags = true # %processUnusedTags% | Set true to output unused tags in data tab | boolean
---context:way # following code refers to way-tags
diff --git a/misc/scripts/mapcreation/brouter.sql b/misc/scripts/mapcreation/brouter.sql
index 359f093..4e8a7a9 100644
--- a/misc/scripts/mapcreation/brouter.sql
+++ b/misc/scripts/mapcreation/brouter.sql
@@ -2,6 +2,845 @@
-- formatted by https://sqlformat.darold.net/
SET client_encoding TO UTF8;
+-- prepare the lines table with a new index and a new column
+SELECT
+ now();
+
+ANALYZE;
+
+SELECT
+ now();
+
+SELECT
+ osm_id,
+ highway,
+ maxspeed,
+ way,
+ waterway,
+ li.natural,
+ width,
+ oneway,
+ st_length (way) / st_length (ST_Transform (way, 4326)::geography) AS merca_coef INTO TABLE lines_bis
+FROM
+ lines li;
+
+SELECT
+ now();
+
+DROP TABLE lines;
+
+ALTER TABLE lines_bis RENAME TO lines;
+
+CREATE INDEX lines_osm_id_idx ON lines (osm_id) WITH (fillfactor = '100');
+
+CREATE INDEX lines_way_idx ON public.lines USING gist (way) WITH (fillfactor = '100');
+
+ANALYZE lines;
+
+-- generation of pseudo-tags
+-- 1: noise
+-- create a table with the segments producing noise (motorway, primary and secondary) and a noise_factor for each.
+-- the noise_factor depends on the highway type, maxspeed and oneway
+-- oneway is basically given on motorway segments, in some cases also on primary...
+-- then 2 segments exist on the same route, so noise_factor per segment is lower!!!!
+SELECT
+ now();
+
+SELECT
+ osm_id::bigint,
+ highway,
+ maxspeed,
+ CASE WHEN maxspeed IS NULL
+ OR (NOT (maxspeed ~ '^\d+(\.\d+)?$'))
+ OR maxspeed::numeric > '105' THEN
+ -- maxspeed not defined OR not numeric / usable OR > 105 km/h
+ CASE WHEN highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link') THEN
+ 0.6
+ WHEN highway IN ('primary', 'primary_link') THEN
+ CASE WHEN oneway IS NULL
+ OR oneway NOT IN ('yes', 'true', '1') THEN
+ 0.66
+ ELSE
+ 0.45
+ END
+ WHEN highway IN ('secondary') THEN
+ 0.33
+ ELSE
+ 0
+ END
+ WHEN maxspeed::numeric > '75' THEN
+ -- 75 < maxspeed <= 105
+ CASE WHEN highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link') THEN
+ 0.55
+ WHEN highway IN ('primary', 'primary_link') THEN
+ CASE WHEN oneway IS NULL
+ OR oneway NOT IN ('yes', 'true', '1') THEN
+ 0.66
+ ELSE
+ 0.45
+ END
+ WHEN highway IN ('secondary') THEN
+ 0.33
+ ELSE
+ 0
+ END
+ ELSE
+ -- maxspeed <= 75
+ CASE WHEN highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link') THEN
+ 0.4
+ WHEN highway IN ('primary', 'primary_link') THEN
+ CASE WHEN oneway IS NULL
+ OR oneway NOT IN ('yes', 'true', '1') THEN
+ 0.4
+ ELSE
+ 0.3
+ END
+ WHEN highway IN ('secondary') THEN
+ 0.2
+ ELSE
+ 0
+ END
+ END AS noise_factor,
+ way AS way,
+ ST_Buffer (way, 75 * merca_coef) AS way75,
+ merca_coef INTO TABLE noise_emittnew
+FROM
+ lines li
+WHERE
+ highway IS NOT NULL
+ AND highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary');
+
+SELECT
+ now();
+
+CREATE INDEX noise_emittnew_osm_id_idx ON noise_emittnew (osm_id) WITH (fillfactor = '100');
+
+-- modify noise_factor by very small segments
+SELECT
+ now();
+
+UPDATE
+ noise_emittnew
+SET
+ noise_factor = noise_factor * (st_length (way) / merca_coef) / 20
+WHERE (st_length (way) / merca_coef) < 20;
+
+SELECT
+ now();
+
+ANALYZE noise_emittnew;
+
+SELECT
+ now();
+
+-- create a tuple (highway + noise source) of the highways having noise (for perf tuning)
+SELECT
+ dd.osm_id::bigint AS lines_osm_id,
+ dd.highway,
+ dd.merca_coef,
+ dd.way,
+ q.osm_id AS noise_osm_id INTO TABLE tuples_with_noise
+FROM
+ lines dd
+ INNER JOIN noise_emittnew AS q ON ST_Intersects (dd.way, q.way75)
+WHERE
+ dd.highway IS NOT NULL
+ AND dd.highway NOT IN ('proposed', 'construction')
+ AND (st_length (dd.way) / dd.merca_coef) < 40000;
+
+--group by dd.osm_id, dd.highway, dd.merca_coef, dd.way;
+SELECT
+ now();
+
+CREATE INDEX tuples_with_noise_osm_id_idx ON tuples_with_noise (lines_osm_id) WITH (fillfactor = '100');
+
+SELECT
+ now();
+
+ANALYZE tuples_with_noise;
+
+SELECT
+ lines_osm_id AS osm_id,
+ way,
+ merca_coef INTO TABLE lines_with_noise
+FROM
+ tuples_with_noise
+GROUP BY
+ lines_osm_id,
+ merca_coef,
+ way;
+
+SELECT
+ now();
+
+CREATE INDEX lineswithnoise_osm_id_idx ON lines_with_noise (osm_id) WITH (fillfactor = '100');
+
+ANALYZE lines_with_noise;
+
+-- calculate noise using "lines_with_noise"
+-- split each segment with noise into 20 meter sections and calculate the noise per section
+-- the average giving the noise for the segment
+SELECT
+ now();
+
+WITH lines_split AS (
+ SELECT
+ osm_id,
+ merca_coef,
+ ST_LineSubstring (d.way, startfrac, LEAST (endfrac, 1)) AS way,
+ len / merca_coef AS lgt_seg_real
+ FROM (
+ SELECT
+ osm_id,
+ merca_coef,
+ way,
+ st_length (way) len,
+ (20 * merca_coef) sublen
+ FROM
+ lines_with_noise) AS d
+ CROSS JOIN LATERAL (
+ SELECT
+ i,
+ (sublen * i) / len AS startfrac,
+ (sublen * (i + 1)) / len AS endfrac
+ FROM
+ generate_series(0, floor(len / sublen)::integer) AS t (i)
+ -- skip last i if line length is exact multiple of sublen
+ WHERE (sublen * i) / len <> 1.0) AS d2
+)
+SELECT
+ m.osm_id::bigint losmid,
+ m.lgt_seg_real,
+ st_distance (m.way, t.way) / m.merca_coef AS dist,
+ -- the line below delivers the same result as above !!!!!!! but need much more time (* 7 !)
+ -- st_distance(st_transform(m.way, 4326)::geography, st_transform(t.way, 4326)::geography) as distgeog,
+ t.noise_factor INTO TABLE noise_tmp2newz
+FROM
+ lines_split AS m
+ INNER JOIN tuples_with_noise AS q ON m.osm_id = q.lines_osm_id
+ INNER JOIN noise_emittnew t ON t.osm_id = q.noise_osm_id
+WHERE
+ st_distance (m.way, t.way) / m.merca_coef < 75;
+
+SELECT
+ now();
+
+ANALYZE noise_tmp2newz;
+
+-- group
+SELECT
+ now();
+
+-- calculate an indicator per section (1 / d*d here) and reduce the results by taking the average on the osm_segment
+SELECT
+ losmid,
+ m.lgt_seg_real,
+ sum(noise_factor / ((dist + 15) / 15)) / ((m.lgt_seg_real / 20)::integer + 1) AS sum_noise_factor INTO noise_tmp2new
+FROM
+ noise_tmp2newz m
+GROUP BY
+ m.losmid,
+ m.lgt_seg_real;
+
+SELECT
+ now();
+
+DROP TABLE noise_tmp2newz;
+
+DROP TABLE tuples_with_noise;
+
+DROP TABLE noise_emittnew;
+
+ANALYZE noise_tmp2new;
+
+SELECT
+ now();
+
+-- add noise from Airports...
+-- polygons of the international airports
+SELECT
+ name,
+ st_buffer (way, (700 * st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography))) AS way INTO TABLE poly_airportnew
+FROM
+ polygons
+WHERE
+ aeroway = 'aerodrome'
+ AND aerodrome = 'international';
+
+SELECT
+ now();
+
+ANALYZE poly_airportnew;
+
+SELECT
+ m.osm_id::bigint losmid,
+ -- st_area(st_intersection(m.way, q.way)) / (st_area(m.way) * 1.5)
+ -- 1 / 1.5
+ (700 - (st_distance (m.way, q.way) / m.merca_coef)) / (700 * 1.5) AS dist_factor INTO TABLE noise_airportnew
+FROM
+ lines AS m
+ INNER JOIN poly_airportnew AS q ON ST_intersects (m.way, q.way)
+WHERE
+ m.highway IS NOT NULL
+ORDER BY
+ dist_factor DESC;
+
+SELECT
+ now();
+
+ANALYZE noise_airportnew;
+
+SELECT
+ losmid,
+ sum(noise_factor) AS sum_noise_factor INTO TABLE noise_tmp3new
+FROM ((
+ SELECT
+ losmid,
+ sum_noise_factor AS noise_factor
+ FROM
+ noise_tmp2new AS nois1)
+ UNION (
+ SELECT
+ losmid,
+ dist_factor AS noise_factor
+ FROM
+ noise_airportnew AS nois2)) AS nois_sum
+GROUP BY
+ losmid;
+
+SELECT
+ now();
+
+ANALYZE noise_tmp3new;
+
+-- create the noise classes
+SELECT
+ now();
+
+SELECT
+ losmid,
+ CASE WHEN y.sum_noise_factor < 0.06 THEN
+ '1'
+ WHEN y.sum_noise_factor < 0.13 THEN
+ '2'
+ WHEN y.sum_noise_factor < 0.26 THEN
+ '3'
+ WHEN y.sum_noise_factor < 0.45 THEN
+ '4'
+ WHEN y.sum_noise_factor < 0.85 THEN
+ '5'
+ ELSE
+ '6'
+ END AS noise_class INTO TABLE noise_tags
+FROM
+ noise_tmp3new y
+WHERE
+ y.sum_noise_factor > 0.01
+ORDER BY
+ noise_class;
+
+SELECT
+ now();
+
+ANALYZE noise_tags;
+
+SELECT
+ count(*)
+FROM
+ noise_tags;
+
+SELECT
+ noise_class,
+ count(*)
+FROM
+ noise_tags
+GROUP BY
+ noise_class
+ORDER BY
+ noise_class;
+
+-------------------------------------------------------------------------
+-- 2: create tags for river
+-- create a table with the segments and polygons with "river" (or water!)
+SELECT
+ now();
+
+WITH river_from_polygons AS (
+ SELECT
+ osm_id::bigint,
+ way,
+ ST_Buffer (way, 110 * st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography)) AS way2
+ FROM
+ polygons q
+ WHERE
+ q.natural IN ('water', 'bay', 'beach', 'wetland')
+ AND (q.water IS NULL
+ OR q.water NOT IN ('wastewater'))
+ AND st_area (ST_Transform (q.way, 4326)::geography) BETWEEN 1000 AND 5000000000
+),
+river_from_lines AS (
+ SELECT
+ osm_id::bigint,
+ way,
+ ST_Buffer (way, 80 * merca_coef) AS way2
+ FROM
+ lines q
+ WHERE
+ q.waterway IN ('river', 'canal', 'fairway')
+ OR q.natural IN ('coastline')
+ ORDER BY
+ way
+),
+river_coastline AS (
+ SELECT
+ osm_id::bigint,
+ way,
+ ST_Buffer (ST_ExteriorRing (way), 100 * st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography)) AS way2
+ FROM
+ polygons p
+ WHERE
+ st_area (ST_Transform (p.way, 4326)::geography) > 1000
+ AND (p.natural IN ('coastline')
+ AND st_length (way) < 100000)
+ ORDER BY
+ way
+)
+SELECT
+ * INTO river_proxy
+FROM (
+ SELECT
+ *
+ FROM
+ river_from_polygons part1
+ UNION
+ SELECT
+ *
+ FROM
+ river_from_lines part2
+ UNION
+ SELECT
+ *
+ FROM
+ river_coastline part3) AS sumriver;
+
+SELECT
+ now();
+
+CREATE INDEX river_proxy_osm_id_idx ON river_proxy (osm_id) WITH (fillfactor = '100');
+
+ANALYZE river_proxy;
+
+SELECT
+ now();
+
+-- create a tuple (highway + noise source) of the highways in river proxymity (for perf tuning)
+SELECT
+ dd.osm_id::bigint AS lines_osm_id,
+ dd.merca_coef,
+ dd.way,
+ q.osm_id AS river_osm_id INTO TABLE tuples_with_river
+FROM
+ lines dd
+ INNER JOIN river_proxy AS q ON ST_Intersects (dd.way, q.way2)
+WHERE
+ dd.highway IS NOT NULL
+ AND dd.highway NOT IN ('proposed', 'construction')
+ AND (st_length (dd.way) / dd.merca_coef) < 40000;
+
+SELECT
+ now();
+
+CREATE INDEX tuples_with_river_osm_id_idx ON tuples_with_river (lines_osm_id) WITH (fillfactor = '100');
+
+SELECT
+ now();
+
+ANALYZE tuples_with_river;
+
+SELECT
+ now();
+
+-- create a table of highways with river...
+SELECT
+ lines_osm_id AS osm_id,
+ way,
+ merca_coef INTO TABLE lines_with_river
+FROM
+ tuples_with_river
+GROUP BY
+ lines_osm_id,
+ merca_coef,
+ way;
+
+SELECT
+ now();
+
+CREATE INDEX lineswithriver_osm_id_idx ON lines_with_river (osm_id) WITH (fillfactor = '100');
+
+ANALYZE lines_with_river;
+
+SELECT
+ now();
+
+-- calculate river factor using "lines_with_river"
+-- split each segment with river into 20 meter sections and calculate the river per section
+-- the average giving the river_factor for the segment
+WITH lines_split AS (
+ SELECT
+ osm_id,
+ merca_coef,
+ ST_LineSubstring (d.way, startfrac, LEAST (endfrac, 1)) AS way,
+ len / merca_coef AS lgt_seg_real
+ FROM (
+ SELECT
+ osm_id,
+ merca_coef,
+ way,
+ st_length (way) len,
+ (20 * merca_coef) sublen
+ FROM
+ lines_with_river) AS d
+ CROSS JOIN LATERAL (
+ SELECT
+ i,
+ (sublen * i) / len AS startfrac,
+ (sublen * (i + 1)) / len AS endfrac
+ FROM
+ generate_series(0, floor(len / sublen)::integer) AS t (i)
+ -- skip last i if line length is exact multiple of sublen
+ WHERE (sublen * i) / len <> 1.0) AS d2
+)
+SELECT
+ m.osm_id::bigint losmid,
+ m.lgt_seg_real,
+ st_distance (m.way, t.way) / m.merca_coef AS dist INTO TABLE river_tmp2newz
+FROM
+ lines_split AS m
+ INNER JOIN tuples_with_river AS q ON m.osm_id = q.lines_osm_id
+ INNER JOIN river_proxy t ON t.osm_id = q.river_osm_id
+WHERE
+ st_distance (m.way, t.way) / m.merca_coef < 165;
+
+SELECT
+ now();
+
+ANALYZE river_tmp2newz;
+
+SELECT
+ now();
+
+SELECT
+ losmid,
+ m.lgt_seg_real,
+ sum(1 / ((dist + 50) / 50)) / ((m.lgt_seg_real / 20)::integer + 1) AS sum_river_factor INTO river_tmp2new
+FROM
+ river_tmp2newz m
+GROUP BY
+ m.losmid,
+ m.lgt_seg_real;
+
+SELECT
+ now();
+
+DROP TABLE river_tmp2newz;
+
+DROP TABLE tuples_with_river;
+
+DROP TABLE river_proxy;
+
+ANALYZE river_tmp2new;
+
+SELECT
+ now();
+
+SELECT
+ losmid,
+ CASE WHEN y.sum_river_factor < 0.22 THEN
+ '1'
+ WHEN y.sum_river_factor < 0.35 THEN
+ '2'
+ WHEN y.sum_river_factor < 0.5 THEN
+ '3'
+ WHEN y.sum_river_factor < 0.75 THEN
+ '4'
+ WHEN y.sum_river_factor < 0.98 THEN
+ '5'
+ ELSE
+ '6'
+ END AS river_class INTO TABLE river_tags
+FROM
+ river_tmp2new y
+WHERE
+ y.sum_river_factor > 0.03;
+
+SELECT
+ now();
+
+SELECT
+ count(*)
+FROM
+ river_tags;
+
+SELECT
+ river_class,
+ count(*)
+FROM
+ river_tags
+GROUP BY
+ river_class
+ORDER BY
+ river_class;
+
+SELECT
+ now();
+
+-------------------------------------------------------------
+-- create pseudo-tags for forest
+--
+-- create first a table of the polygons with forest
+SELECT
+ now();
+
+SELECT
+ osm_id::bigint,
+ leisure,
+ landuse,
+ p.natural,
+ p.water,
+ way,
+ ST_Buffer (way, 32.15 * st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography)) AS way32 INTO TABLE osm_poly_forest
+FROM
+ polygons p
+WHERE
+ st_area (ST_Transform (p.way, 4326)::geography) > 1500
+ AND ((p.landuse IN ('forest', 'allotments', 'flowerbed', 'orchard', 'vineyard', 'recreation_ground', 'village_green'))
+ OR p.leisure IN ('garden', 'park', 'nature_reserve'))
+ AND st_area (ST_Transform (p.way, 4326)::geography) BETWEEN 5000 AND 5000000000
+ORDER BY
+ way;
+
+SELECT
+ now();
+
+CREATE INDEX osm_poly_forest_osm_id_idx ON osm_poly_forest (osm_id) WITH (fillfactor = '100');
+
+SELECT
+ now();
+
+ANALYZE osm_poly_forest;
+
+-- create a table of the lines within forests (green_factor is nomally 1, but 5 is better to calculate class 6 )
+SELECT
+ now();
+
+SELECT
+ m.osm_id::bigint,
+ m.highway,
+ 6 AS green_factor INTO TABLE lines_within_forest
+FROM
+ lines AS m
+ INNER JOIN osm_poly_forest q ON ST_Within (m.way, q.way)
+WHERE
+ m.highway IS NOT NULL
+GROUP BY
+ m.osm_id,
+ m.highway,
+ m.way;
+
+CREATE INDEX lines_within_forest_osm_id_idx ON lines_within_forest (osm_id) WITH (fillfactor = '100');
+
+SELECT
+ now();
+
+ANALYZE lines_within_forest;
+
+-- create a tuple table (lines+polygons) of the lines near but not within forests
+SELECT
+ m.osm_id::bigint AS lines_osm_id,
+ m.highway,
+ m.merca_coef,
+ m.way AS lines_way,
+ q.osm_id AS forest_osm_id INTO TABLE tuples_limit_forest
+FROM
+ lines AS m
+ INNER JOIN osm_poly_forest AS q ON ST_Intersects (m.way, q.way32)
+WHERE
+ m.highway IS NOT NULL
+ AND m.highway NOT IN ('proposed', 'construction')
+ AND (st_length (m.way) / m.merca_coef) < 40000
+ AND m.osm_id::bigint NOT IN (
+ SELECT
+ osm_id
+ FROM
+ lines_within_forest);
+
+SELECT
+ now();
+
+CREATE INDEX tuples_lines_osm_id_idx ON tuples_limit_forest (lines_osm_id) WITH (fillfactor = '100');
+
+SELECT
+ now();
+
+ANALYZE tuples_limit_forest;
+
+SELECT
+ now();
+
+-- create a table with only the lines near but not within forests
+SELECT
+ m.lines_osm_id osm_id,
+ m.highway,
+ m.merca_coef,
+ m.lines_way AS way INTO TABLE lines_limit_forest
+FROM
+ tuples_limit_forest AS m
+GROUP BY
+ m.lines_osm_id,
+ m.highway,
+ m.merca_coef,
+ m.lines_way;
+
+SELECT
+ now();
+
+CREATE INDEX lines_limit_forest_osm_id_idx ON lines_limit_forest (osm_id) WITH (fillfactor = '100');
+
+SELECT
+ now();
+
+ANALYZE lines_limit_forest;
+
+-- calculate the forest factor (or green_factor) for the lines at forest limit..
+-- spilt the line into 20 meter sections
+-- calculate the distance section-forest
+SELECT
+ now();
+
+WITH lines_split AS (
+ SELECT
+ osm_id,
+ highway,
+ merca_coef,
+ ST_LineSubstring (d.way, startfrac, LEAST (endfrac, 1)) AS way,
+ len / merca_coef AS lgt_seg_real
+ FROM (
+ SELECT
+ osm_id,
+ highway,
+ merca_coef,
+ way,
+ st_length (way) len,
+ (20 * merca_coef) sublen
+ FROM
+ lines_limit_forest) AS d
+ CROSS JOIN LATERAL (
+ SELECT
+ i,
+ (sublen * i) / len AS startfrac,
+ (sublen * (i + 1)) / len AS endfrac
+ FROM
+ generate_series(0, floor(len / sublen)::integer) AS t (i)
+ -- skip last i if line length is exact multiple of sublen
+ WHERE (sublen * i) / len <> 1.0) AS d2
+)
+SELECT
+ m.osm_id,
+ lgt_seg_real,
+ st_distance (m.way, t.way) / m.merca_coef AS dist INTO TABLE forest_tmp2newz
+FROM
+ lines_split AS m
+ INNER JOIN tuples_limit_forest AS q ON m.osm_id = q.lines_osm_id
+ INNER JOIN osm_poly_forest t ON t.osm_id = q.forest_osm_id
+WHERE
+ st_distance (m.way, t.way) / m.merca_coef < 65;
+
+SELECT
+ now();
+
+ANALYZE forest_tmp2newz;
+
+SELECT
+ now();
+
+SELECT
+ m.osm_id,
+ m.lgt_seg_real,
+ sum(1 / ((dist + 25) / 25)) / ((m.lgt_seg_real / 20)::integer + 1) AS green_factor INTO forest_tmp2new
+FROM
+ forest_tmp2newz m
+GROUP BY
+ m.osm_id,
+ m.lgt_seg_real;
+
+SELECT
+ now();
+
+ANALYZE forest_tmp2new;
+
+DROP TABLE forest_tmp2newz;
+
+DROP TABLE osm_poly_forest;
+
+DROP TABLE tuples_limit_forest;
+
+SELECT
+ now();
+
+-- merge lines_within_forest with lines_limit_forest
+WITH forest_tmp3new AS (
+ SELECT
+ *
+ FROM (
+ SELECT
+ osm_id,
+ green_factor
+ FROM
+ forest_tmp2new AS part1
+ UNION
+ SELECT
+ osm_id,
+ green_factor
+ FROM
+ lines_within_forest) AS part2
+)
+SELECT
+ y.osm_id losmid,
+ CASE WHEN y.green_factor < 0.32 THEN
+ '1'
+ WHEN y.green_factor < 0.5 THEN
+ '2'
+ WHEN y.green_factor < 0.7 THEN
+ '3'
+ WHEN y.green_factor < 0.92 THEN
+ '4'
+ WHEN y.green_factor < 5 THEN
+ '5'
+ ELSE
+ '6'
+ END AS forest_class INTO TABLE forest_tags
+FROM
+ forest_tmp3new y
+WHERE
+ y.green_factor > 0.1;
+
+ANALYZE forest_tags;
+
+SELECT
+ count(*)
+FROM
+ forest_tags;
+
+SELECT
+ forest_class,
+ count(*)
+FROM
+ forest_tags
+GROUP BY
+ forest_class
+ORDER BY
+ forest_class;
+
SELECT
now();
@@ -21,133 +860,10 @@ $$
LANGUAGE plpgsql
SECURITY INVOKER;
--- create new tables for tuning
---
-SELECT
- osm_id::bigint,
- highway,
- waterway,
- li.natural,
- width,
- maxspeed,
- CASE WHEN maxspeed IS NULL THEN
- 0
- --when not isnumeric(maxspeed) then 0
- WHEN NOT (maxspeed ~ '^\d+(\.\d+)?$') THEN
- 0
- WHEN maxspeed::numeric > '105' THEN
- 1
- WHEN maxspeed::numeric > '75' THEN
- 2
- ELSE
- 3
- END AS maxspeed_class
- -- "buffer radius" was initially created with 50 meters at a latitude of 50 degrees... ==> ST_Buffer(way,50)
- -- but, using geometry "projection", to get same results by a calculation of the planet (latitude between -80, +85) this value should be adapted to the latitude of the highways...
-,
- --
- ST_Buffer (way, 32.15 * st_length (ST_Transform (way, 3857)) / st_length (ST_Transform (way, 4326)::geography)) AS way INTO TABLE osm_line_buf_50
-FROM
- lines li
-WHERE
- highway IS NOT NULL
- OR waterway IN ('river', 'canal', 'fairway')
- OR (li.natural = 'coastline'
- AND st_length (way) < 100000);
-
SELECT
now();
--- modify "way" by large waterways !!" (example Rhein ==> width = 400 ...) enlarge a bit the "50 meter" buffer
-UPDATE
- osm_line_buf_50
-SET
- way = st_buffer (way, (width::numeric / 10))
-WHERE
- waterway = 'river'
- AND width IS NOT NULL
- AND (width ~ '^[0-9\.]+$')
- AND width::numeric > 15
- AND width::numeric < 2500;
-
-SELECT
- osm_id::bigint,
- leisure,
- landuse,
- p.natural,
- p.water,
- ST_Buffer (way, 32.15 * st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography)) AS way INTO TABLE osm_poly_buf_50
-FROM
- polygons p
-WHERE
- -- do not consider small surfaces
- st_area (p.way) > 1000
- AND (p.natural IN ('water', 'bay', 'beach', 'wetland')
- OR p.landuse IN ('forest', 'allotments', 'flowerbed', 'orchard', 'vineyard', 'recreation_ground', 'village_green')
- OR p.leisure IN ('garden', 'park', 'nature_reserve'));
-
--- by forest no buffer !
-SELECT
- osm_id::bigint,
- leisure,
- landuse,
- p.natural,
- p.water,
- way INTO TABLE osm_poly_no_buf
-FROM
- polygons p
-WHERE
- -- do not consider small surfaces
- st_area (p.way) > 1000
- AND (p.natural IN ('water', 'bay', 'beach', 'costline', 'wetland')
- OR p.landuse IN ('forest', 'allotments', 'flowerbed', 'orchard', 'vineyard', 'recreation_ground', 'village_green')
- OR p.leisure IN ('garden', 'park', 'nature_reserve'));
-
-SELECT
- osm_id::bigint,
- leisure,
- landuse,
- p.natural,
- p.water,
- ST_Buffer (way, 45 * st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography)) AS way INTO TABLE osm_poly_buf_120
-FROM
- osm_poly_buf_50 p;
-
--- for coastline special case
-SELECT
- osm_id::bigint,
- leisure,
- landuse,
- p.natural,
- p.water,
- ST_Buffer (ST_ExteriorRing (way), 64 * st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography)) AS way INTO TABLE osm_poly_coastline_buf_100
-FROM
- polygons p
-WHERE
- -- do not consider small surfaces
- st_area (p.way) > 1000
- AND (p.natural IN ('coastline')
- AND st_length (way) < 100000);
-
---CREATE INDEX osm_poly_coastline_ind ON public.osm_poly_coastline_buf_100 USING gist (way) WITH (fillfactor='100');
-SELECT
- * INTO TABLE osm_line_water
-FROM
- osm_line_buf_50 q
-WHERE
- q.waterway IN ('river', 'canal', 'fairway')
- OR q.natural IN ('coastline');
-
-CREATE INDEX osm_line_water_ind ON public.osm_line_water USING gist (way) WITH (fillfactor = '100');
-
-SELECT
- now();
-
--- create indexes
-CREATE INDEX osm_line_buf_50_idx ON public.osm_line_buf_50 USING gist (way) WITH (fillfactor = '100');
-
-ANALYZE;
-
+-- create tables for traffic
SELECT
osm_id,
highway,
@@ -166,6 +882,168 @@ CREATE INDEX primsecter15k_idx1 ON public.primsecter15k USING gist (way) WITH (f
CREATE INDEX primsecter15k_idx0 ON public.primsecter15k USING gist (way0) WITH (fillfactor = '100');
+ANALYZE primsecter15k;
+
+SELECT
+ now();
+
+-- consistency check on population, first evaluate and documents it
+WITH cities_x AS (
+ SELECT
+ a.name,
+ a.name_en,
+ place,
+ osm_id,
+ replace(a.population, '.', '')::bigint population,
+ a.way
+ FROM
+ cities a
+ WHERE
+ a.population IS NOT NULL
+ AND isnumeric (a.population)
+ AND a.place IN ('village', 'town', 'city', 'municipality'))
+SELECT
+ name,
+ name_en,
+ place,
+ population,
+ osm_id
+FROM
+ cities_x a
+WHERE (place = 'village'
+ AND a.population > 90000)
+ OR (place = 'town'
+ AND a.population > 1500000)
+ OR (place = 'city'
+ AND a.population > 40000000)
+ORDER BY
+ place,
+ Population DESC;
+
+WITH cities_relx AS (
+ SELECT
+ a.name,
+ a.name_en,
+ place,
+ osm_id,
+ replace(a.population, '.', '')::bigint population,
+ a.way
+ FROM
+ cities_rel a
+ WHERE
+ a.population IS NOT NULL
+ AND isnumeric (a.population)
+ AND a.place IN ('village', 'town', 'city', 'municipality'))
+SELECT
+ name,
+ name_en,
+ place,
+ population,
+ osm_id
+FROM
+ cities_relx a
+WHERE (place = 'village'
+ AND a.population > 90000)
+ OR (place = 'town'
+ AND a.population > 1500000)
+ OR (place = 'city'
+ AND a.population > 40000000)
+ OR (place IS NULL
+ AND a.population > 40000000)
+ORDER BY
+ place,
+ Population DESC;
+
+-- now store the inconstencies
+WITH cities_x AS (
+ SELECT
+ a.name,
+ a.name_en,
+ place,
+ osm_id,
+ replace(a.population, '.', '')::bigint population,
+ a.way
+ FROM
+ cities a
+ WHERE
+ a.population IS NOT NULL
+ AND isnumeric (a.population)
+ AND a.place IN ('village', 'town', 'city', 'municipality'))
+SELECT
+ name,
+ name_en,
+ place,
+ population,
+ osm_id INTO TABLE cities_incon
+FROM
+ cities_x a
+WHERE (place = 'village'
+ AND a.population > 90000)
+ OR (place = 'town'
+ AND a.population > 1500000)
+ OR (place = 'city'
+ AND a.population > 40000000)
+ORDER BY
+ place,
+ Population DESC;
+
+WITH cities_relx AS (
+ SELECT
+ a.name,
+ a.name_en,
+ place,
+ osm_id,
+ replace(a.population, '.', '')::bigint population,
+ a.way
+ FROM
+ cities_rel a
+ WHERE
+ a.population IS NOT NULL
+ AND isnumeric (a.population)
+ AND a.place IN ('village', 'town', 'city', 'municipality'))
+SELECT
+ name,
+ name_en,
+ place,
+ population,
+ osm_id INTO TABLE cities_rel_incon
+FROM
+ cities_relx a
+WHERE (place = 'village'
+ AND a.population > 90000)
+ OR (place = 'town'
+ AND a.population > 1500000)
+ OR (place = 'city'
+ AND a.population > 40000000)
+ OR (place IS NULL
+ AND a.population > 40000000)
+ORDER BY
+ place,
+ Population DESC;
+
+-- and eliminate the inconsistencies
+UPDATE
+ cities
+SET
+ population = 0
+WHERE
+ osm_id IN (
+ SELECT
+ osm_id
+ FROM
+ cities_incon);
+
+UPDATE
+ cities_rel
+SET
+ population = 0
+WHERE
+ osm_id IN (
+ SELECT
+ osm_id
+ FROM
+ cities_rel_incon);
+
SELECT
now();
@@ -173,18 +1051,25 @@ SELECT
-- clean the cities table (when population is null or population is not numeric or unusable)
SELECT
a.name,
+ a.name_en,
replace(a.population, '.', '')::bigint population,
- a.way INTO cities_ok
+ a.way INTO TABLE cities_ok
FROM
cities a
WHERE
a.population IS NOT NULL
AND isnumeric (a.population)
- AND a.place IN ('town', 'city', 'municipality');
+ AND a.place IN ('village', 'town', 'city', 'municipality');
+
+ANALYZE cities_ok;
+
+SELECT
+ now();
-- clean the cities_rel table (when population is not numeric or unusable)
SELECT
a.name AS name,
+ a.name_en AS name_en,
a.place AS place,
a.admin_level,
CASE WHEN a.population IS NOT NULL
@@ -193,20 +1078,26 @@ SELECT
ELSE
NULL
END AS population,
- a.way INTO cities_rel_ok
+ a.way INTO TABLE cities_rel_ok
FROM
cities_rel a
WHERE
- boundary = 'administrative';
+ boundary IN ('administrative', 'ceremonial');
CREATE INDEX cities_ok_idx ON public.cities_ok USING gist (way) WITH (fillfactor = '100');
CREATE INDEX cities_rel_ok_idx ON public.cities_rel_ok USING gist (way) WITH (fillfactor = '100');
--- select town + population + way starting with cities_ok ... (to catch special cases as ex. "Berlin" which is tagged with "admin_level=4")
+SELECT
+ now();
+
+ANALYZE cities_rel_ok;
+
+-- select town + population + way starting with cities_ok .... (to catch specials cases as ex. "Berlin" which is tagged with "admin_level=4")
--
SELECT
a.name AS name,
+ a.name_en AS name_en,
st_x (a.way),
st_y (a.way),
a.population,
@@ -295,7 +1186,7 @@ LIMIT 1)
AND a.name = b.name
AND st_intersects (a.way, b.way))
LIMIT 1)
--- Berlin admin_level=4!
+-- Berlin admin_level=4! , but Beijing/Shangai administrative-regions have the same name and area>20000 km*2 !!!
WHEN (
SELECT
way
@@ -324,7 +1215,7 @@ LIMIT 1)
cities_rel_ok b
WHERE (st_area (b.way) / 1000000 < 10000
AND b.admin_level IS NULL
- AND b.place IN ('city', 'town')
+ AND b.place IN ('town', 'city', 'village', 'municipality')
AND a.name = b.name
AND st_intersects (a.way, b.way))
LIMIT 1) IS NOT NULL THEN
@@ -335,7 +1226,7 @@ LIMIT 1)
cities_rel_ok b
WHERE (st_area (b.way) / 1000000 < 10000
AND b.admin_level IS NULL
- AND b.place IN ('city', 'town')
+ AND b.place IN ('town', 'city', 'village', 'municipality')
AND a.name = b.name
AND st_intersects (a.way, b.way))
LIMIT 1)
@@ -347,7 +1238,7 @@ LIMIT 1)
cities_rel_ok b
WHERE (st_area (b.way) / 1000000 < 10000
AND b.admin_level = '2'
- AND b.place IN ('city', 'town')
+ AND b.place IN ('town', 'city', 'village', 'municipality')
AND a.name = b.name
AND st_intersects (a.way, b.way))
LIMIT 1) IS NOT NULL THEN
@@ -358,7 +1249,7 @@ LIMIT 1)
cities_rel_ok b
WHERE (st_area (b.way) / 1000000 < 10000
AND b.admin_level = '2'
- AND b.place IN ('city', 'town')
+ AND b.place IN ('town', 'city', 'village', 'municipality')
AND a.name = b.name
AND st_intersects (a.way, b.way))
LIMIT 1)
@@ -376,9 +1267,17 @@ FROM
ORDER BY
name;
--- select town + population + way starting with cities_rel_ok ...
+CREATE INDEX cities_intermed3_idx ON public. cities_intermed3 USING gist (way) WITH (fillfactor = '100');
+
+SELECT
+ now();
+
+ANALYZE cities_intermed3;
+
+-- select town + population + way starting with cities_rel_ok ....
SELECT
a.name AS name,
+ a.name_en AS name_en,
st_area (a.way) st_area,
CASE WHEN a.population IS NOT NULL THEN
a.population
@@ -398,43 +1297,52 @@ FROM
cities_rel_ok a
WHERE
a.admin_level = '8'
+ AND (a.place IS NULL
+ OR a.place IN ('town', 'city', 'village', 'municipality'))
ORDER BY
a.name;
--- merge
SELECT
- name,
- max(population) AS population,
- way,
- max(way0) AS way0,
- st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography) AS merca_coef INTO cities_intermed5
-FROM ((
- SELECT
- name,
- population,
- way,
- way0
- FROM
- cities_intermed3)
- UNION (
- SELECT
- name,
- population,
- way,
- way0
- FROM
- cities_intermed4)) a
-WHERE
- population IS NOT NULL
- -- and population > 20000
-GROUP BY
- name,
- way
-ORDER BY
- population;
+ now();
+-- merge
+WITH intermed5 AS (
+ SELECT
+ name,
+ max(name_en) AS name_en,
+ max(population) AS population,
+ way,
+ max(way0) AS way0,
+ st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography) AS merca_coef
+ FROM ((
+ SELECT
+ name,
+ name_en,
+ population,
+ way,
+ way0
+ FROM
+ cities_intermed3)
+ UNION (
+ SELECT
+ name,
+ name_en,
+ population,
+ way,
+ way0
+ FROM
+ cities_intermed4)) a
+ WHERE
+ population IS NOT NULL
+ GROUP BY
+ name,
+ way
+ ORDER BY
+ population
+)
SELECT
name,
+ name_en,
population,
way,
CASE WHEN way0 IS NULL THEN
@@ -443,565 +1351,16 @@ SELECT
way0::geometry
END AS way0,
merca_coef INTO TABLE cities_all
-FROM
- cities_intermed5;
-
-SELECT
- now();
-
--- create tags for noise
--- create raw data for noise coming from cars
--- when several highways-segments are producing noise, aggregate the noises using the "ST_Union" of the segments!
--- (better as using "sum" or "max" that do not deliver good factors)
-SELECT
- * INTO TABLE osm_line_noise
-FROM
- osm_line_buf_50 q
-WHERE
- q.highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link', 'primary', 'primary_link', 'secondary');
-
-CREATE INDEX osm_line_noise_ind ON public.osm_line_noise USING gist (way) WITH (fillfactor = '100');
-
-SELECT
- now();
-
-SELECT
- m.osm_id losmid,
- m.highway lhighway,
- q.highway AS qhighway,
- q.maxspeed_class,
- st_area (st_intersection (m.way, ST_Union (q.way))) / st_area (m.way) AS noise_factor INTO TABLE noise_part0
-FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_line_noise AS q ON ST_Intersects (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- AND q.highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link')
- AND q.maxspeed_class < 1.1
-GROUP BY
- losmid,
- lhighway,
- m.way,
- q.highway,
- q.maxspeed_class
-ORDER BY
- noise_factor DESC;
-
-SELECT
- now();
-
-SELECT
- m.osm_id losmid,
- m.highway lhighway,
- q.highway AS qhighway,
- q.maxspeed_class,
- st_area (st_intersection (m.way, ST_Union (q.way))) / (1.5 * st_area (m.way)) AS noise_factor INTO TABLE noise_part1
-FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_line_noise AS q ON ST_Intersects (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- AND q.highway IN ('motorway', 'motorway_link', 'trunk', 'trunk_link')
- AND q.maxspeed_class >= 1.1
-GROUP BY
- losmid,
- lhighway,
- m.way,
- q.highway,
- q.maxspeed_class
-ORDER BY
- noise_factor DESC;
-
-SELECT
- now();
-
-SELECT
- m.osm_id losmid,
- m.highway lhighway,
- q.highway AS qhighway,
- q.maxspeed_class,
- st_area (st_intersection (m.way, ST_Union (q.way))) / (2 * st_area (m.way)) AS noise_factor INTO TABLE noise_part2
-FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_line_noise AS q ON ST_Intersects (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- AND q.highway IN ('primary', 'primary_link')
- AND q.maxspeed_class < 2.1
-GROUP BY
- losmid,
- lhighway,
- m.way,
- q.highway,
- q.maxspeed_class
-ORDER BY
- noise_factor DESC;
-
-SELECT
- now();
-
-SELECT
- m.osm_id losmid,
- m.highway lhighway,
- q.highway AS qhighway,
- q.maxspeed_class,
- st_area (st_intersection (m.way, ST_Union (q.way))) / (3 * st_area (m.way)) AS noise_factor INTO TABLE noise_part3
-FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_line_noise AS q ON ST_Intersects (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- AND q.highway IN ('primary', 'primary_link')
- AND q.maxspeed_class >= 2.1
-GROUP BY
- losmid,
- lhighway,
- m.way,
- q.highway,
- q.maxspeed_class
-ORDER BY
- noise_factor DESC;
-
-SELECT
- now();
-
-SELECT
- m.osm_id losmid,
- m.highway lhighway,
- q.highway AS qhighway,
- q.maxspeed_class,
- st_area (st_intersection (m.way, ST_Union (q.way))) / (3 * st_area (m.way)) AS noise_factor INTO TABLE noise_part4
-FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_line_noise AS q ON ST_Intersects (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- AND q.highway IN ('secondary')
- AND q.maxspeed_class < 2.1
-GROUP BY
- losmid,
- lhighway,
- m.way,
- q.highway,
- q.maxspeed_class
-ORDER BY
- noise_factor DESC;
-
-SELECT
- now();
-
-SELECT
- m.osm_id losmid,
- m.highway lhighway,
- q.highway AS qhighway,
- q.maxspeed_class,
- st_area (st_intersection (m.way, ST_Union (q.way))) / (5 * st_area (m.way)) AS noise_factor INTO TABLE noise_part5
-FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_line_noise AS q ON ST_Intersects (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- AND q.highway IN ('secondary')
- AND q.maxspeed_class >= 2.1
-GROUP BY
- losmid,
- lhighway,
- m.way,
- q.highway,
- q.maxspeed_class
-ORDER BY
- noise_factor DESC;
-
-SELECT
- now();
-
--- MERGE
-SELECT
- losmid,
- sum(noise_factor) AS sum_noise_factor INTO TABLE noise_tmp2
FROM (
SELECT
- losmid,
- noise_factor
+ *
FROM
- noise_part0
- UNION
- SELECT
- losmid,
- noise_factor
- FROM
- noise_part1
- UNION
- SELECT
- losmid,
- noise_factor
- FROM
- noise_part2
- UNION
- SELECT
- losmid,
- noise_factor
- FROM
- noise_part3
- UNION
- SELECT
- losmid,
- noise_factor
- FROM
- noise_part4
- UNION
- SELECT
- losmid,
- noise_factor
- FROM
- noise_part5) AS abcd
-GROUP BY
- losmid
-ORDER BY
- sum_noise_factor DESC;
+ intermed5 a) b;
SELECT
now();
--- noise coming from airports
-SELECT
- name,
- st_buffer (way, (643 * st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 3857)) / st_length (ST_Transform (st_makeline (st_startpoint (way), st_centroid (way)), 4326)::geography))) AS way INTO TABLE poly_airport
-FROM
- polygons
-WHERE
- aeroway = 'aerodrome'
- AND aerodrome = 'international';
-
-SELECT
- m.osm_id losmid,
- st_area (st_intersection (m.way, q.way)) / (st_area (m.way) * 1.5) AS dist_factor INTO TABLE noise_airport
-FROM
- osm_line_buf_50 AS m
- INNER JOIN poly_airport AS q ON ST_intersects (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- --GROUP BY losmid, m.way
-ORDER BY
- dist_factor DESC;
-
--- add car & airport noises
-SELECT
- losmid,
- sum(noise_factor) AS sum_noise_factor INTO TABLE noise_tmp3
-FROM ((
- SELECT
- losmid,
- sum_noise_factor AS noise_factor
- FROM
- noise_tmp2 AS nois1)
- UNION (
- SELECT
- losmid,
- dist_factor AS noise_factor
- FROM
- noise_airport AS nois2)) AS nois_sum
-GROUP BY
- losmid;
-
--- create the noise classes
-SELECT
- losmid,
- CASE WHEN y.sum_noise_factor < 0.1 THEN
- '1'
- WHEN y.sum_noise_factor < 0.25 THEN
- '2'
- WHEN y.sum_noise_factor < 0.4 THEN
- '3'
- WHEN y.sum_noise_factor < 0.55 THEN
- '4'
- WHEN y.sum_noise_factor < 0.8 THEN
- '5'
- ELSE
- '6'
- END AS noise_class INTO TABLE noise_tags
-FROM
- noise_tmp3 y
-WHERE
- y.sum_noise_factor > 0.01;
-
-SELECT
- count(*)
-FROM
- noise_tags;
-
-SELECT
- noise_class,
- count(*)
-FROM
- noise_tags
-GROUP BY
- noise_class
-ORDER BY
- noise_class;
-
-DROP TABLE noise_tmp2;
-
-SELECT
- now();
-
--- create tags for river
-SELECT
- xid,
- sum(water_river_see) AS river_see INTO TABLE river_tmp
-FROM (
- SELECT
- m.osm_id AS xid,
- st_area (st_intersection (m.way, ST_Union (q.way))) / st_area (m.way) AS water_river_see
- FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_poly_buf_120 AS q ON ST_Intersects (m.way, q.way)
- WHERE
- m.highway IS NOT NULL
- -- and st_area(q.way) > 90746 !!! filter on very small surfaces was set above !!!!!!!!!
- AND q.natural IN ('water', 'bay', 'beach', 'wetland')
- AND (q.water IS NULL
- OR q.water NOT IN ('wastewater'))
- AND (st_area (ST_Transform (q.way, 4326)::geography) / 1000000) < 5000
- GROUP BY
- m.osm_id,
- m.way
- UNION
- SELECT
- m.osm_id AS xid,
- st_area (st_intersection (m.way, ST_Union (q.way))) / st_area (m.way) AS water_river_see
- FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_poly_coastline_buf_100 AS q ON ST_Intersects (m.way, q.way)
- WHERE
- m.highway IS NOT NULL
- -- and st_area(q.way) > 90746 !!! filter on very small surfaces was set above !!!!!!!!!
- GROUP BY
- m.osm_id,
- m.way
- UNION
- SELECT
- m.osm_id AS xid,
- st_area (st_intersection (m.way, ST_Union (q.way))) / st_area (m.way) AS water_river_see
- FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_line_water AS q ON ST_Intersects (m.way, q.way)
- WHERE
- m.highway IS NOT NULL
- AND (st_area (ST_Transform (q.way, 4326)::geography) / 1000000) < 5000
- GROUP BY
- m.osm_id,
- m.way) AS abcd
-GROUP BY
- xid
-ORDER BY
- river_see DESC;
-
-SELECT
- y.xid losmid,
- CASE WHEN y.river_see < 0.17 THEN
- '1'
- WHEN y.river_see < 0.35 THEN
- '2'
- WHEN y.river_see < 0.57 THEN
- '3'
- WHEN y.river_see < 0.80 THEN
- '4'
- WHEN y.river_see < 0.95 THEN
- '5'
- ELSE
- '6'
- END AS river_class INTO TABLE river_tags
-FROM
- river_tmp y
-WHERE
- y.river_see > 0.05;
-
-SELECT
- count(*)
-FROM
- river_tags;
-
-SELECT
- river_class,
- count(*)
-FROM
- river_tags
-GROUP BY
- river_class
-ORDER BY
- river_class;
-
-SELECT
- now();
-
--- create tags for forest
-SELECT
- m.osm_id,
- m.highway,
- st_area (st_intersection (m.way, ST_Union (q.way))) / st_area (m.way) AS green_factor INTO TABLE forest_tmp
-FROM
- osm_line_buf_50 AS m
- INNER JOIN osm_poly_no_buf AS q ON ST_Intersects (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- AND ((q.landuse IN ('forest', 'allotments', 'flowerbed', 'orchard', 'vineyard', 'recreation_ground', 'village_green'))
- OR q.leisure IN ('garden', 'park', 'nature_reserve'))
- AND (st_area (ST_Transform (q.way, 4326)::geography) / 1000000) < 5000
-GROUP BY
- m.osm_id,
- m.highway,
- m.way
-ORDER BY
- green_factor DESC;
-
---
-SELECT
- y.osm_id losmid,
- CASE WHEN y.green_factor < 0.1 THEN
- NULL
- WHEN y.green_factor < 0.2 THEN
- '1'
- WHEN y.green_factor < 0.4 THEN
- '2'
- WHEN y.green_factor < 0.6 THEN
- '3'
- WHEN y.green_factor < 0.8 THEN
- '4'
- WHEN y.green_factor < 0.98 THEN
- '5'
- ELSE
- '6'
- END AS forest_class INTO TABLE forest_tags
-FROM
- forest_tmp y
-WHERE
- y.green_factor > 0.1;
-
-SELECT
- count(*)
-FROM
- forest_tags;
-
-SELECT
- forest_class,
- count(*)
-FROM
- forest_tags
-GROUP BY
- forest_class
-ORDER BY
- forest_class;
-
-SELECT
- now();
-
--- create "town" tags
--- get the highways within the town
-SELECT
- m.osm_id losmid,
- m.highway lhighway,
- CASE WHEN q.population::decimal > '2000000' THEN
- 1
- WHEN q.population::decimal > '1000000' THEN
- 0.8
- WHEN q.population::decimal > '400000' THEN
- 0.6
- WHEN q.population::decimal > '150000' THEN
- 0.4
- WHEN q.population::decimal > '80000' THEN
- 0.2
- ELSE
- 0.1
- END AS town_factor INTO TABLE town_tmp
-FROM
- osm_line_buf_50 AS m
- --INNER JOIN cities_all AS q ON ST_Intersects(m.way, q.way)
- INNER JOIN cities_all AS q ON ST_Within (m.way, q.way)
-WHERE
- m.highway IS NOT NULL
- AND q.population > '50000'
-ORDER BY
- town_factor DESC;
-
---
-SELECT
- losmid,
- CASE WHEN y.town_factor = 0.1 THEN
- '1'
- WHEN y.town_factor = 0.2 THEN
- '2'
- WHEN y.town_factor = 0.4 THEN
- '3'
- WHEN y.town_factor = 0.6 THEN
- '4'
- WHEN y.town_factor = 0.8 THEN
- '5'
- ELSE
- '6'
- END AS town_class INTO TABLE town_tags
-FROM (
- SELECT
- losmid,
- max(town_factor) AS town_factor
- FROM
- town_tmp y
- GROUP BY
- losmid) y;
-
-SELECT
- count(*)
-FROM
- town_tags;
-
-SELECT
- town_class,
- count(*)
-FROM
- town_tags
-GROUP BY
- town_class
-ORDER BY
- town_class;
-
---
--- subtract the ways from town with a green tag (because administrative surface are sometimes too large)
---
-DELETE FROM town_tags
-WHERE losmid IN (
- SELECT
- losmid
- FROM
- forest_tags
- WHERE
- forest_class NOT IN ('1'));
-
-DELETE FROM town_tags
-WHERE losmid IN (
- SELECT
- losmid
- FROM
- river_tags
- WHERE
- river_class NOT IN ('1'));
-
-SELECT
- count(*)
-FROM
- town_tags;
-
-SELECT
- town_class,
- count(*)
-FROM
- town_tags
-GROUP BY
- town_class
-ORDER BY
- town_class;
-
-SELECT
- now();
+ANALYZE cities_all;
-------------------------------------------
-- create tags for TRAFFIC
@@ -1035,7 +1394,6 @@ FROM
INNER JOIN cities_all AS q ON ST_DWithin (m.way0, q.way0, ((3215 * q.merca_coef) + ((64300 * q.merca_coef) * q.population / (q.population + 10000))))
WHERE
m.highway IS NOT NULL
- --and m.highway in ('primary','primary_link','secondary', 'secondary_link', 'tertiary')
AND q.population > 200
GROUP BY
m.osm_id,
@@ -1047,8 +1405,10 @@ ORDER BY
SELECT
now();
+ANALYZE traffic_tmp;
+
-- prepare some special tables
--- the intersections motorway_link with primary/secondary/tertiary deliver the motorway accesses...
+-- the intersections motorway_link with primary/secondary/tertiary deliver the motorway acccesses....
SELECT
* INTO TABLE lines_link
FROM
@@ -1086,6 +1446,8 @@ CREATE INDEX motorway_access_idx3 ON public.motorway_access USING gist (way3) WI
SELECT
now();
+ANALYZE motorway_access;
+
-- find out all the primary/secondary/tertiary within 1000 m and 2000 m from a motorway access
SELECT
now();
@@ -1109,7 +1471,7 @@ SELECT
SELECT
m.osm_id losmid,
- sum(st_length (q.way) / (6430 * merca_coef)) motorway_factor INTO TABLE motorway_access_2000
+ sum(st_length (q.way) / (6430 * q.merca_coef)) motorway_factor INTO TABLE motorway_access_2000
FROM
lines AS m
INNER JOIN motorway_access AS q ON ST_Intersects (m.way, q.way3)
@@ -1124,6 +1486,8 @@ ORDER BY
SELECT
now();
+ANALYZE motorway_access_2000;
+
--
-- special regions: mountain_range with "peaks" ==> few highways ==> higher traffic !!!
-- calculate the "peak_density"
@@ -1139,6 +1503,7 @@ FROM
INNER JOIN peak AS q ON ST_Intersects (m.way2, q.way)
WHERE (q.ele ~ '^[0-9\.]+$')
AND q.ele::decimal > 400
+ -- where (q.ele not ~ '^\d+(\.\d+)?$') and q.ele :: decimal > 400
GROUP BY
m.osm_id,
m.way
@@ -1164,17 +1529,21 @@ FROM
WHERE (landuse IN ('industrial', 'retail'))
OR (aeroway = 'aerodrome'
AND aerodrome = 'international')
- --where landuse in ('industrial', 'retail')
- --where landuse in ('industrial')
AND (plant_method IS NULL
OR plant_method NOT IN ('photovoltaic'))
AND (plant_source IS NULL
OR plant_source NOT IN ('solar', 'wind'));
+SELECT
+ now();
+
+ANALYZE poly_industri;
+
SELECT
name,
way,
ST_Centroid (way) way0,
+ ST_Buffer (way, 12860 * merca_coef) AS way2,
st_area (way) * power(50 / (32.15 * merca_coef), 2) areaReal,
merca_coef INTO industri
FROM
@@ -1197,7 +1566,7 @@ SELECT
END AS industrial_factor INTO industri_tmp
FROM
primsecter15k AS m
- INNER JOIN industri AS q ON ST_dwithin (m.way0, q.way0, (12860 * q.merca_coef))
+ INNER JOIN industri AS q ON ST_intersects (m.way0, q.way2)
GROUP BY
m.osm_id,
m.highway,
@@ -1363,7 +1732,7 @@ GROUP BY
SELECT
now();
--- Do not apply the positive effect of "motorway density" in proximity of motorway accesses!!!!
+-- Do not apply the positiv effect of "motorway density" in proximity of motorway accesses!!!!
UPDATE
except_all
SET
@@ -1375,11 +1744,11 @@ WHERE
FROM
motorway_access_2000);
--- quite direct at motorway accesses set a negative effect !!!!
+-- quite direct at motorway accesses set a negativ effect !!!!
UPDATE
except_all
SET
- motorway_factor = - 15
+ motorway_factor = -15
WHERE
losmid IN (
SELECT
@@ -1427,6 +1796,120 @@ GROUP BY
ORDER BY
traffic_class;
+-- create town tags.................
+-- create "town" tags
+-- get the highways within the town
+SELECT
+ m.osm_id losmid,
+ m.highway lhighway,
+ CASE WHEN q.population::decimal > '2000000' THEN
+ 1
+ WHEN q.population::decimal > '1000000' THEN
+ 0.8
+ WHEN q.population::decimal > '400000' THEN
+ 0.6
+ WHEN q.population::decimal > '150000' THEN
+ 0.4
+ WHEN q.population::decimal > '80000' THEN
+ 0.2
+ ELSE
+ 0.1
+ END AS town_factor INTO TABLE town_tmp
+FROM
+ lines AS m
+ INNER JOIN cities_all AS q ON ST_Within (m.way, q.way)
+WHERE
+ m.highway IS NOT NULL
+ AND q.population > '50000'
+ORDER BY
+ town_factor DESC;
+
+SELECT
+ now();
+
+ANALYSE town_tmp;
+
+--
+SELECT
+ losmid::bigint,
+ CASE WHEN y.town_factor = 0.1 THEN
+ '1'
+ WHEN y.town_factor = 0.2 THEN
+ '2'
+ WHEN y.town_factor = 0.4 THEN
+ '3'
+ WHEN y.town_factor = 0.6 THEN
+ '4'
+ WHEN y.town_factor = 0.8 THEN
+ '5'
+ ELSE
+ '6'
+ END AS town_class INTO TABLE town_tags
+FROM (
+ SELECT
+ losmid,
+ max(town_factor) AS town_factor
+ FROM
+ town_tmp y
+ GROUP BY
+ losmid) y;
+
+ANALYSE town_tags;
+
+SELECT
+ count(*)
+FROM
+ town_tags;
+
+SELECT
+ town_class,
+ count(*)
+FROM
+ town_tags
+GROUP BY
+ town_class
+ORDER BY
+ town_class;
+
+--
+-- substract the ways from town with a green tag (because administrative surface are some times too large)
+--
+DELETE FROM town_tags
+WHERE losmid IN (
+ SELECT
+ losmid
+ FROM
+ forest_tags
+ WHERE
+ forest_class NOT IN ('1'));
+
+DELETE FROM town_tags
+WHERE losmid IN (
+ SELECT
+ losmid
+ FROM
+ river_tags
+ WHERE
+ river_class NOT IN ('1'));
+
+SELECT
+ count(*)
+FROM
+ town_tags;
+
+SELECT
+ town_class,
+ count(*)
+FROM
+ town_tags
+GROUP BY
+ town_class
+ORDER BY
+ town_class;
+
+SELECT
+ now();
+
--
-- put all tags together in 1 table (1 "direct" access per way in mapcreator)
--
@@ -1452,7 +1935,7 @@ ORDER BY
CREATE INDEX all_tags_ind ON all_tags (losmid, noise_class, river_class, forest_class, town_class, traffic_class) WITH (fillfactor = '100');
-ANALYSE;
+ANALYSE all_tags;
SELECT
now();
diff --git a/misc/scripts/mapcreation/brouter_cfg.lua b/misc/scripts/mapcreation/brouter_cfg.lua
index 07604f6..6998a69 100644
--- a/misc/scripts/mapcreation/brouter_cfg.lua
+++ b/misc/scripts/mapcreation/brouter_cfg.lua
@@ -18,6 +18,7 @@ tables.lines = osm2pgsql.define_way_table('lines', {
{ column = 'waterway', type = 'text' },
{ column = 'natural', type = 'text' },
{ column = 'width', type = 'text' },
+ { column = 'oneway', type = 'text' },
{ column = 'way', type = 'linestring', projection = srid, not_null = true },
})
@@ -43,6 +44,7 @@ tables.polygons = osm2pgsql.define_area_table('polygons', {
tables.cities = osm2pgsql.define_node_table('cities', {
{ column = 'name', type = 'text' },
+ { column = 'name_en', type = 'text' },
{ column = 'place', type = 'text' },
{ column = 'admin_level', type = 'text' },
{ column = 'osm_id', type = 'text' },
@@ -56,6 +58,7 @@ tables.cities_rel = osm2pgsql.define_relation_table('cities_rel', {
{ column = 'admin_level', type = 'text' },
{ column = 'boundary', type = 'text' },
{ column = 'name', type = 'text' },
+ { column = 'name_en', type = 'text' },
{ column = 'place', type = 'text' },
{ column = 'osm_id', type = 'text' },
{ column = 'population', type = 'text' },
@@ -114,10 +117,11 @@ end
function osm2pgsql.process_node(object)
- if (object.tags.place == 'city' or object.tags.place == 'town' or object.tags.place == 'municipality') and has_area_tags(object.tags) then
+if (object.tags.place == 'city' or object.tags.place == 'town' or object.tags.place == 'village' or object.tags.place == 'municipality') and has_area_tags(object.tags) then
tables.cities:insert({
osm_id = object.id,
name = object.tags.name,
+ name_en = object.tags['name:en'],
place = object.tags.place,
admin_level = object.tags.admin_level,
population = object.tags.population,
@@ -166,6 +170,7 @@ function osm2pgsql.process_way(object)
natural = object.tags.natural,
width = object.tags.width,
maxspeed = object.tags.maxspeed,
+ oneway = object.tags.oneway,
way = object:as_linestring()
})
end
@@ -202,6 +207,7 @@ function osm2pgsql.process_relation(object)
boundary = object.tags.boundary,
admin_level = object.tags.admin_level,
name = object.tags.name,
+ name_en = object.tags['name:en'],
place = object.tags.place,
population = object.tags.population,
osm_id = object.id,