diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/MainForm.form b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/MainForm.form
index e7800803..d23b96fe 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/MainForm.form
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/MainForm.form
@@ -1208,7 +1208,7 @@
-
+
@@ -1225,18 +1225,26 @@
-
+
+
-
+
+
+
+
+
+
+
-
+
+
@@ -2896,7 +2904,7 @@
-
+
diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/MainForm.java b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/MainForm.java
index 1aeb8e05..12457f26 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/MainForm.java
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/MainForm.java
@@ -208,6 +208,7 @@ private void initComponents() {
routeMemberOptionPanel = new javax.swing.JPanel();
skipNodesWithRoleEmptyCb = new javax.swing.JCheckBox();
skipNodesWithRoleStopCb = new javax.swing.JCheckBox();
+ skipNodesWithRoleStopWithoutMatchinPlatformCb = new javax.swing.JCheckBox();
removePlatformsNotInGtfsFromOSMRelationCb = new javax.swing.JCheckBox();
gtfsDataPanel = new javax.swing.JPanel();
rbURL = new javax.swing.JRadioButton();
@@ -443,18 +444,24 @@ private void initComponents() {
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
optionsPanel.add(routeOptionsPanel, gridBagConstraints);
- routeMemberOptionPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Route members options"));
+ routeMemberOptionPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Route members options (applies only to PTv2 relations)"));
routeMemberOptionPanel.setLayout(new javax.swing.BoxLayout(routeMemberOptionPanel, javax.swing.BoxLayout.Y_AXIS));
skipNodesWithRoleEmptyCb.setSelected(true);
- skipNodesWithRoleEmptyCb.setText("Remove nodes with empty role (required for PTv2)");
+ skipNodesWithRoleEmptyCb.setText("Remove nodes having empty role (mandatory for PTv2)");
+ skipNodesWithRoleEmptyCb.setEnabled(false);
routeMemberOptionPanel.add(skipNodesWithRoleEmptyCb);
- skipNodesWithRoleStopCb.setText("Remove nodes with role 'stop' (only if PTv2 is enabled)");
+ skipNodesWithRoleStopCb.setText("Remove all nodes having role 'stop'");
skipNodesWithRoleStopCb.setActionCommand("Remove nodes with 'stop' role");
routeMemberOptionPanel.add(skipNodesWithRoleStopCb);
- removePlatformsNotInGtfsFromOSMRelationCb.setText("Remove platform nodes without Gtfs match (only if PTv2 is enabled)");
+ skipNodesWithRoleStopWithoutMatchinPlatformCb.setSelected(true);
+ skipNodesWithRoleStopWithoutMatchinPlatformCb.setText("Remove nodes having role 'stop' that don't match a platform (recommended)");
+ routeMemberOptionPanel.add(skipNodesWithRoleStopWithoutMatchinPlatformCb);
+
+ removePlatformsNotInGtfsFromOSMRelationCb.setSelected(true);
+ removePlatformsNotInGtfsFromOSMRelationCb.setText("Remove platforms without Gtfs match (recommended)");
routeMemberOptionPanel.add(removePlatformsNotInGtfsFromOSMRelationCb);
gridBagConstraints = new java.awt.GridBagConstraints();
@@ -672,7 +679,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
.addGroup(revertChangesetPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(revertChangesetField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(changesetLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 373, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 376, Short.MAX_VALUE)
.addComponent(revertButton)
.addContainerGap())
);
@@ -787,19 +794,23 @@ private void compareButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN
processingOptions.add(ProcessingOptions.SKIP_GTFS_STATIONS);
}
if (skipNodesWithRoleEmptyCb.isSelected()) {
- processingOptions.add(ProcessingOptions.SKIP_NODES_WITH_ROLE_EMPTY);
+ processingOptions.add(ProcessingOptions.SKIP_NODES_HAVING_ROLE_EMPTY);
}
if (createAsPTv2Cb.isSelected()) {
processingOptions.add(ProcessingOptions.CREATE_ROUTE_AS_PTV2);
+ processingOptions.add(ProcessingOptions.SKIP_NODES_HAVING_ROLE_EMPTY);
}
if (removePlatformsNotInGtfsFromOSMRelationCb.isSelected()) {
- processingOptions.add(ProcessingOptions.REMOVE_PLATFORMS_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION);
+ processingOptions.add(ProcessingOptions.SKIP_NODES_HAVING_ROLE_PLATFORM_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION);
}
if (dontReplaceExistingOSMRouteColorCb.isSelected()) {
processingOptions.add(ProcessingOptions.DONT_REPLACE_EXISING_OSM_ROUTE_COLOR);
}
if (skipNodesWithRoleStopCb.isSelected()) {
- processingOptions.add(ProcessingOptions.SKIP_NODES_WITH_ROLE_STOP);
+ processingOptions.add(ProcessingOptions.SKIP_NODES_HAVING_ROLE_STOP_ALL);
+ }
+ if (skipNodesWithRoleStopWithoutMatchinPlatformCb.isSelected()) {
+ processingOptions.add(ProcessingOptions.SKIP_NODES_HAVING_ROLE_STOP_WITHOUT_MATCHING_PLATFORM);
}
if (dontAddGtfsRouteTextColorCb.isSelected()) {
processingOptions.add(ProcessingOptions.DONT_ADD_GTFS_ROUTE_TEXT_COLOR_TO_ROUTE);
@@ -1121,6 +1132,7 @@ public void propertyChange(PropertyChangeEvent evt) {
private javax.swing.JCheckBox skipGtfsStationsCb;
private javax.swing.JCheckBox skipNodesWithRoleEmptyCb;
private javax.swing.JCheckBox skipNodesWithRoleStopCb;
+ private javax.swing.JCheckBox skipNodesWithRoleStopWithoutMatchinPlatformCb;
private javax.swing.JPanel stopOptionsPanel;
private javax.swing.JTextArea taskOutput;
private javax.swing.JLabel threshold_label;
diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/ReportViewer.java b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/ReportViewer.java
index 6380c364..5b38af74 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/ReportViewer.java
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/ReportViewer.java
@@ -21,6 +21,7 @@
import edu.usf.cutr.go_sync.object.Stop;
import edu.usf.cutr.go_sync.osm.HttpRequest;
import edu.usf.cutr.go_sync.tag_defs;
+import edu.usf.cutr.go_sync.task.CompareData;
import edu.usf.cutr.go_sync.task.UploadData;
import edu.usf.cutr.go_sync.tools.OsmDistance;
import java.awt.Color;
@@ -1168,99 +1169,145 @@ private void updateMemberList(Route selectedNewRoute, Route selectedOsmRoute, St
LinkedHashSet newMembersWaysOnly = new LinkedHashSet();
LinkedHashSet tempem = new LinkedHashSet();
ArrayList skippedMembersIndex = new ArrayList<>();
- ArrayList skippedMembersIndexNodes = new ArrayList<>();
int indexInNewMember = 0;
- for (RelationMember m : aRoute.getOsmMembers()) {
- if (m.getRef().startsWith("-")) {
- skippedMembersIndex.add(indexInNewMember);
- }
- newMembers.add(m);
- indexInNewMember++;
- }
+ newMembers.addAll(aRoute.getOsmMembers());
tempem.addAll(osmMembers);
- EnumSet strategy = MainForm.processingOptions;
-
- int indexInNewMemberNodes = indexInNewMember;
-
for (RelationMember m : tempem) {
RelationMember matchMember = aRoute.getOsmMember(m.getRef());
if (matchMember != null) {
matchMember.setStatus("both GTFS dataset and OSM server");
} else {
if (PTversion != null && PTversion.equals("2")) {
+ // Rearrange nodes & ways so that nodes (platforms, stops...) come before ways (ways with empty role)
if (m.getType().equals("node")) {
- if (strategy.contains(ProcessingOptions.SKIP_NODES_WITH_ROLE_EMPTY)) {
- if (m.getRole().isEmpty()) {
- skippedMembersIndexNodes.add(indexInNewMemberNodes);
- }
- }
- if (strategy.contains(ProcessingOptions.SKIP_NODES_WITH_ROLE_STOP)) {
- if (m.getRole().equals("stop") || m.getRole().equals("stop_exit_only") || m.getRole().equals("stop_entry_only")) {
- skippedMembersIndexNodes.add(indexInNewMemberNodes);
- }
- }
- if (strategy.contains(ProcessingOptions.REMOVE_PLATFORMS_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION)) {
- if (m.getRole().equals("platform") || m.getRole().equals("platform_exit_only") || m.getRole().equals("platform_entry_only")) {
- skippedMembersIndexNodes.add(indexInNewMemberNodes);
- }
- }
newMembersNodesOnly.add(m);
- indexInNewMemberNodes++;
}
if (m.getType().equals("way")) {
- if (m.getRole().equals("platform") || m.getRole().equals("platform_exit_only") || m.getRole().equals("platform_entry_only")) {
- // Ways can also be set as platforms. Support this case too. They should be at the top with the other platforms/stops.
- if (strategy.contains(ProcessingOptions.REMOVE_PLATFORMS_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION)) {
- if (m.getRole().equals("platform") || m.getRole().equals("platform_exit_only") || m.getRole().equals("platform_entry_only")) {
- skippedMembersIndexNodes.add(indexInNewMemberNodes);
- }
- }
+ // Ways can also be set as platforms. Support this case too. They should be at the top with the other platforms/stops.
+ if (m.getRoleForFinalOutput().equals("platform") || m.getRoleForFinalOutput().equals("platform_exit_only") || m.getRoleForFinalOutput().equals("platform_entry_only")) {
newMembersNodesOnly.add(m);
- indexInNewMemberNodes++;
} else {
- // roles "backward", "forward" & "reverse" should not be used anymore on public transport routes
- // https://wiki.openstreetmap.org/wiki/Relation:route
- if (m.getRole().equals("backward") || m.getRole().equals("forward") || m.getRole().equals("reverse")) {
- m.setRole("");
- }
newMembersWaysOnly.add(m);
}
}
} else {
newMembers.add(m);
- indexInNewMember++;
}
}
}
if (PTversion != null && PTversion.equals("2")) {
- newMembers.addAll(newMembersNodesOnly);
- newMembers.addAll(newMembersWaysOnly);
- skippedMembersIndex.addAll(skippedMembersIndexNodes);
- }
+ // For PTv2 group platform/stops together
+ int index = 0;
+ LinkedHashSet platforms = new LinkedHashSet();
+ platforms.addAll(newMembers);
+ LinkedHashSet stops = new LinkedHashSet();
+ for (RelationMember m : newMembersNodesOnly) {
+
+ // Fix member role in case it doesn't match the real public_transport value of the member (eg. member having role stop, while it actually is a platform).
+ String roleSuffix = "";
+ if (m.getRole().endsWith("_exit_only")) {
+ roleSuffix = "_exit_only";
+ } else if (m.getRole().endsWith("_entry_only")) {
+ roleSuffix = "_entry_only";
+ }
+ switch (m.getRefOsmPublicTransportType()) {
+ case "stop_position":
+ if (!m.getRole().startsWith("stop")) {
+ m.setRole("stop" + roleSuffix);
+ }
+ break;
+ case "platform":
+ if (!m.getRole().startsWith("platform")) {
+ m.setRole("platform" + roleSuffix);
+ }
+ break;
+ default:
+ break;
+ }
- indexInNewMember = newMembers.size();
- if (!osmMembers.containsAll(newMembers)) {
- for (RelationMember m : osmMembers) {
- boolean addToSkippedMembersIndex = false;
- if (strategy.contains(ProcessingOptions.SKIP_NODES_WITH_ROLE_EMPTY)) {
- if (m.getType().equals("node") && m.getRole().isEmpty()) {
- addToSkippedMembersIndex = true;
- }
+ if (m.getRoleForFinalOutput().equals("platform") || m.getRoleForFinalOutput().equals("platform_exit_only") || m.getRoleForFinalOutput().equals("platform_entry_only")) {
+ platforms.add(m);
}
- if (strategy.contains(ProcessingOptions.SKIP_NODES_WITH_ROLE_STOP)) {
- if (m.getType().equals("node") && m.getRole().isEmpty()) {
- addToSkippedMembersIndex = true;
- }
+ if (m.getRoleForFinalOutput().equals("stop") || m.getRoleForFinalOutput().equals("stop_exit_only") || m.getRoleForFinalOutput().equals("stop_entry_only")) {
+ stops.add(m);
}
- if (strategy.contains(ProcessingOptions.REMOVE_PLATFORMS_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION)) {
- if (m.getRole().equals("platform") || m.getRole().equals("platform_exit_only") || m.getRole().equals("platform_entry_only")) {
- addToSkippedMembersIndex = true;
+ index++;
+ }
+
+ LinkedHashSet newMembersNodesOnlyGrouped = new LinkedHashSet();
+ LinkedHashSet addedStops = new LinkedHashSet();
+ for (RelationMember p : platforms) {
+ newMembersNodesOnlyGrouped.add(p);
+ if (shouldSkipMember(PTversion, p, null, aRoute.getOsmMembers())) {
+ // if p will be skipped (eg. if it is platform not in gtfs) don't proceed with trying to add the nearby stop.
+ // Otherwise if the stop matches a platform that is not part of the gtfs trip but currently present in the OSM relation,
+ // it will be kept, even if the platform is not in the final relation for upload (which is not wanted).
+ continue;
+ }
+ for (RelationMember s : stops) {
+ double dist = OsmDistance.distVincenty(p.getLat(), p.getLon(), s.getLat(), s.getLon());
+ if (dist < CompareData.MAX_PLATFORM_STOP_DISTANCE) {
+ newMembersNodesOnlyGrouped.add(s);
+ switch (p.getRole()) {
+ case "platform":
+ s.setRole("stop");
+ break;
+ case "platform_exit_only":
+ s.setRole("stop_exit_only");
+ break;
+ case "platform_entry_only":
+ s.setRole("stop_entry_only");
+ break;
+ default:
+ break;
+ }
+ addedStops.add(s);
}
}
+ }
+
+ LinkedHashSet remainingStops = new LinkedHashSet();
+ remainingStops.addAll(stops);
+ remainingStops.removeAll(addedStops);
+
+ // For PTv2: we must have first the nodes, then the ways.
+ newMembers.clear();
+ newMembers.addAll(newMembersNodesOnlyGrouped);
+ newMembers.addAll(remainingStops);
+ newMembers.addAll(newMembersWaysOnly);
+
+ // Mark members to be removed & apply other modifications as asked in processingOptions.
+ for (RelationMember m : newMembers) {
+ if (m.getType().equals("way") && (m.getRole().equals("backward") || m.getRole().equals("forward") || m.getRole().equals("reverse"))) {
+ // roles "backward", "forward" & "reverse" should not be used anymore on public transport PTv2 routes
+ // https://wiki.openstreetmap.org/wiki/Relation:route
+ m.setRole("");
+ }
+ if (shouldSkipMember(PTversion, m, remainingStops, aRoute.getOsmMembers())) {
+ skippedMembersIndex.add(indexInNewMember);
+ }
+ indexInNewMember++;
+ }
+ }
+
+ // Skip members the OSM id of which is negative
+ indexInNewMember = 0;
+ for (RelationMember m : newMembers) {
+ if (m.getRef().startsWith("-")) {
+ skippedMembersIndex.add(indexInNewMember);
+ }
+ indexInNewMember++;
+ }
+
+ indexInNewMember = newMembers.size();
+ if (!newMembers.containsAll(osmMembers)) {
+ //System.out.println("Adding osm members not yet in new Members.");
+ for (RelationMember m : osmMembers) {
+ boolean addToSkippedMembersIndex = shouldSkipMember(PTversion, m, null, aRoute.getOsmMembers());
if (newMembers.add(m)) {
if (addToSkippedMembersIndex) {
skippedMembersIndex.add(indexInNewMember);
@@ -1323,7 +1370,7 @@ private void updateMemberList(Route selectedNewRoute, Route selectedOsmRoute, St
String status = t.getStatus();
if(status.equals(criteria) || criteria.equals("all")) {
String v = t.getGtfsId();
- String suffix = " (" + t.getType() + "/" + t.getRole() + "/" + t.getRef() + ")";
+ String suffix = " (" + t.getType() + "/" + t.getRoleForFinalOutput() + "/" + t.getRef() + ")";
if (v == null || v.equals("none") || v.equals("")) {
v = suffix.strip();
} else {
@@ -1349,6 +1396,47 @@ private void updateMemberList(Route selectedNewRoute, Route selectedOsmRoute, St
totalNewMembersLabel.setText(Integer.toString(newMembersForSave.size()));
}
+ private boolean shouldSkipMember(String PTversion, RelationMember m, LinkedHashSet remainingStops, LinkedHashSet agencyMembers) {
+ if (!PTversion.equals("2")) {
+ return false;
+ }
+
+ if (remainingStops != null && remainingStops.contains(m)) {
+ if (MainForm.processingOptions.contains(ProcessingOptions.SKIP_NODES_HAVING_ROLE_STOP_WITHOUT_MATCHING_PLATFORM)) {
+ return true;
+ }
+ }
+ if (m.getType().equals("node")) {
+ if (MainForm.processingOptions.contains(ProcessingOptions.SKIP_NODES_HAVING_ROLE_EMPTY)) {
+ if (m.getRole().isEmpty()) {
+ return true;
+ }
+ }
+ if (MainForm.processingOptions.contains(ProcessingOptions.SKIP_NODES_HAVING_ROLE_STOP_ALL)) {
+ if (m.getRoleForFinalOutput().equals("stop") || m.getRoleForFinalOutput().equals("stop_exit_only") || m.getRoleForFinalOutput().equals("stop_entry_only")) {
+ return true;
+ }
+ }
+ if (MainForm.processingOptions.contains(ProcessingOptions.SKIP_NODES_HAVING_ROLE_PLATFORM_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION)) {
+ if (!agencyMembers.contains(m)
+ && (m.getRoleForFinalOutput().equals("platform") || m.getRoleForFinalOutput().equals("platform_exit_only") || m.getRoleForFinalOutput().equals("platform_entry_only"))) {
+ return true;
+ }
+ }
+ }
+ if (m.getType().equals("way")) {
+ if (m.getRoleForFinalOutput().equals("platform") || m.getRoleForFinalOutput().equals("platform_exit_only") || m.getRoleForFinalOutput().equals("platform_entry_only")) {
+ if (MainForm.processingOptions.contains(ProcessingOptions.SKIP_NODES_HAVING_ROLE_PLATFORM_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION)) {
+ if (!agencyMembers.contains(m)
+ && (m.getRoleForFinalOutput().equals("platform") || m.getRoleForFinalOutput().equals("platform_exit_only") || m.getRoleForFinalOutput().equals("platform_entry_only"))) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
private void updateRouteCategory(Route[] selectedCategory){
gtfsRoutes = selectedCategory;
Arrays.sort(gtfsRoutes);
diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/object/RouteMemberTableModel.java b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/object/RouteMemberTableModel.java
index f718d8ce..19366626 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/object/RouteMemberTableModel.java
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/gui/object/RouteMemberTableModel.java
@@ -26,7 +26,7 @@
*/
public class RouteMemberTableModel extends AbstractTableModel {
private String[] columnNames = {"GTFS Member List",
- "OSM Member List",
+ "OSM Member List (ordered by 'New Member List' if PTv2)",
"New Member List"};
private Object[][] data;
diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/object/ProcessingOptions.java b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/object/ProcessingOptions.java
index 3e41185a..904bdaa3 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/object/ProcessingOptions.java
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/object/ProcessingOptions.java
@@ -29,9 +29,10 @@ public enum ProcessingOptions {
DONT_ADD_GTFS_AGENCY_ID_TO_ROUTE,
// For Route Members
- SKIP_NODES_WITH_ROLE_EMPTY,
- SKIP_NODES_WITH_ROLE_STOP,
+ SKIP_NODES_HAVING_ROLE_EMPTY,
+ SKIP_NODES_HAVING_ROLE_STOP_ALL,
+ SKIP_NODES_HAVING_ROLE_STOP_WITHOUT_MATCHING_PLATFORM,
CREATE_ROUTE_AS_PTV2,
- REMOVE_PLATFORMS_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION;
+ SKIP_NODES_HAVING_ROLE_PLATFORM_NOT_IN_GTFS_TRIP_FROM_OSM_RELATION;
}
diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/object/RelationMember.java b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/object/RelationMember.java
index d6cfd7d2..82b1457d 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/object/RelationMember.java
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/object/RelationMember.java
@@ -23,10 +23,15 @@
*/
public class RelationMember {
private String ref, type, role, status, gtfsId="";
- public RelationMember(String ref, String type, String role){
+ private String lat, lon;
+ private String refOsmPublicTransportType;
+ public RelationMember(String ref, String type, String role, String lat, String lon, String refOsmPublicTransportType) {
this.ref = ref;
this.type = type;
this.role = role;
+ this.lat = lat;
+ this.lon = lon;
+ this.refOsmPublicTransportType = refOsmPublicTransportType;
}
public RelationMember(RelationMember rm){
@@ -35,6 +40,9 @@ public RelationMember(RelationMember rm){
this.role = rm.getRole();
this.gtfsId = rm.getGtfsId();
this.status = rm.getStatus();
+ this.lat = rm.getLat();
+ this.lon = rm.getLon();
+ this.refOsmPublicTransportType = rm.getRefOsmPublicTransportType();
}
public String getRef(){
@@ -49,6 +57,30 @@ public String getRole(){
return role;
}
+ public String getRoleForFinalOutput() {
+ // Get the role/public_transport_type from the referenced osm object.
+ String cur_role = role;
+ String new_role = role;
+ if (refOsmPublicTransportType == null) {
+ return role;
+ }
+ if (!refOsmPublicTransportType.equals("stop_position") && !refOsmPublicTransportType.equals("platform")) {
+ return role;
+ }
+ if (refOsmPublicTransportType.equals("stop_position")) {
+ new_role = "stop";
+ }
+ if (refOsmPublicTransportType.equals("platform")) {
+ new_role = "platform";
+ }
+ if (role.endsWith("_exit_only")) {
+ return new_role + "_exit_only";
+ } else if (role.endsWith("_entry_only")) {
+ return new_role + "_entry_only";
+ }
+ return role;
+ }
+
public void setRole(String role) {
this.role = role;
}
@@ -61,6 +93,14 @@ public String getGtfsId(){
return gtfsId;
}
+ public String getRefOsmPublicTransportType() {
+ return refOsmPublicTransportType;
+ }
+
+ public void setRefOsmPublicTransportType(String refOsmPublicTransportType) {
+ this.refOsmPublicTransportType = refOsmPublicTransportType;
+ }
+
public int compareTo(Object o){
RelationMember rm = (RelationMember) o;
if(this.ref.equals(rm.getRef()) && this.type.equals(rm.getType())){
@@ -83,6 +123,22 @@ public String getStatus(){
return status;
}
+ public String getLat() {
+ return lat;
+ }
+
+ public String getLon() {
+ return lon;
+ }
+
+ public void setLat(String lat) {
+ this.lat = lat;
+ }
+
+ public void setLon(String lon) {
+ this.lon = lon;
+ }
+
@Override
public boolean equals(Object o){
if (o instanceof RelationMember) {
diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/osm/HttpRequest.java b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/osm/HttpRequest.java
index 55c2065e..25a287c8 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/osm/HttpRequest.java
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/osm/HttpRequest.java
@@ -199,11 +199,27 @@ public ArrayList getExistingBusStopsTags(){
public ArrayList getExistingBusRelations(String left, String bottom, String right, String top) throws InterruptedException{
// String urlSuffix = "/api/0.6/relation[route=bus][bbox="+left+","+bottom+","+right+","+top+"]";
// String[] hosts = {"http://open.mapquestapi.com/xapi","http://www.informationfreeway.org"};
- String urlSuffix = "?relation[route=bus][bbox="+left+","+bottom+","+right+","+top+"]";
- String[] hosts = {"http://www.overpass-api.de/api/xapi_meta","http://overpass.openstreetmap.ru/cgi/xapi_meta"};
+
+ String content = "";
+ content += "";
+ content += "";
+ content += "";
+ content += "";
+ content += "";
+ content += " ";
+ content += "";
+ content += "";
+ content += "";
+ content = content.replace("left", left).replace("right", right).replace("bottom", bottom).replace("north", top);
+ System.out.println(content);
+
+ //String urlSuffix = "?relation[route=bus][bbox="+left+","+bottom+","+right+","+top+"]";
+ //String[] hosts = {"http://www.overpass-api.de/api/xapi_meta","http://overpass.openstreetmap.ru/cgi/xapi_meta"};
+ String[] hosts = {"http://overpass-api.de/api/interpreter", "http://api.openstreetmap.fr/oapi/interpreter", "http://overpass.osm.rambler.ru/cgi/interpreter",};
try {
// get data from server
- String s = sendRequest(hosts, urlSuffix, "GET", "");
+ //String s = sendRequest(hosts, urlSuffix, "GET", "");
+ String s = sendRequest(hosts, "", "POST", content);
InputSource inputSource = new InputSource(new StringReader(s));
// get data from file - need to remove this for REAL APPLICATION
// InputSource inputSource = new InputSource("DataFromServerRELATION.osm");
diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/task/CompareData.java b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/task/CompareData.java
index 4438d96c..b1f5147f 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/task/CompareData.java
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/task/CompareData.java
@@ -123,7 +123,7 @@ public class CompareData extends OsmTask{
// private final double DELTA = 0.001; // ~400m in Lat and 400m in Lon 0.00001 ~= 1.108m in Lat and 0.983 in Lon
// private final double RANGE = 100; // FIXME bus stop is within 400 meters
-
+ public static final double MAX_PLATFORM_STOP_DISTANCE = 30.0; // in meters.
private String fileNameInStops;
private String fileNameInTrips;
@@ -634,11 +634,14 @@ public void compareRouteData() throws InterruptedException{
// Add gtfs stops as members
String OsmNodeId = String.valueOf(-count);
String gtfsStopId = rvstop.getValue().getStop_id();
+ String type;
if (osmStopIdByGtfsStopId.containsKey(gtfsStopId)) {
OsmNodeId = osmStopIdByGtfsStopId.get(rvstop.getValue().getStop_id());
+ type = osmStopTypeByGtfsStopId.get(gtfsStopId);
} else {
-
+ type = "node";
}
+
String role;
if (!rvstop.getValue().getDrop_off_type().equals("1")
&& rvstop.getValue().getPickup_type().equals("1")) {
@@ -650,10 +653,24 @@ public void compareRouteData() throws InterruptedException{
role = "platform";
}
+ String lat, lon, publicTransportType;
+ if (osmIdToOSMNodexIndex.get(OsmNodeId) == null) {
+ lat = "0";
+ lon = "0";
+ publicTransportType = "platform";
+ } else {
+ lat = OSMNodes.get(osmIdToOSMNodexIndex.get(OsmNodeId)).getLat();
+ lon = OSMNodes.get(osmIdToOSMNodexIndex.get(OsmNodeId)).getLon();
+ publicTransportType = (String) OSMTags.get(osmIdToOSMNodexIndex.get(OsmNodeId)).get(tag_defs.OSM_STOP_TYPE_KEY);
+ }
+
RelationMember rm = new RelationMember(
OsmNodeId,
- osmStopTypeByGtfsStopId.get(gtfsStopId),
- role);
+ type,
+ role,
+ lat,
+ lon,
+ publicTransportType);
rm.setStatus("GTFS dataset");
rm.setGtfsId(gtfsStopId);
r.addOsmMember(rm);
diff --git a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/tools/parser/RouteParser.java b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/tools/parser/RouteParser.java
index 123af6cd..ac5063b5 100644
--- a/GO_Sync/src/main/java/edu/usf/cutr/go_sync/tools/parser/RouteParser.java
+++ b/GO_Sync/src/main/java/edu/usf/cutr/go_sync/tools/parser/RouteParser.java
@@ -20,6 +20,7 @@
import java.util.ArrayList;
import java.util.Hashtable;
import edu.usf.cutr.go_sync.object.RelationMember;
+import java.util.HashMap;
import java.util.LinkedHashSet;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.Attributes;
@@ -37,11 +38,23 @@ public class RouteParser extends DefaultHandler {
//xmlTags ----------- xmlMembers
private ArrayList xmlTags;
private ArrayList> xmlMembers;
- public RouteParser(){
+ private HashMap nodes, ways, nodeWayPtValue;
+ boolean inWay, inNode;
+ String nodeWayId;
+ int ndcount;
+
+ public RouteParser() {
xmlRelations = new ArrayList();
xmlTags = new ArrayList();
xmlMembers = new ArrayList>();
+ nodes = new HashMap<>();
+ ways = new HashMap<>();
+ nodeWayPtValue = new HashMap<>();
+ inWay = false;
+ inNode = false;
+ ndcount = 0;
}
+
@Override public void startElement(String namespaceURI, String localName, String qname, Attributes attributes) throws SAXException {
if (qname.equals("relation")) {
AttributesImpl attImpl = new AttributesImpl(attributes);
@@ -49,16 +62,40 @@ public RouteParser(){
tempTag = new Hashtable(); // start to collect tags of that relation
tempMembers = new LinkedHashSet();
}
- if (tempTag!=null && qname.equals("tag")) {
- AttributesImpl attImpl = new AttributesImpl(attributes);
- tempTag.put(attImpl.getValue("k"), attImpl.getValue("v")); // insert key and value of that tag into Hashtable
+ if (qname.equals("tag")) {
+ if (tempTag != null) {
+ AttributesImpl attImpl = new AttributesImpl(attributes);
+ tempTag.put(attImpl.getValue("k"), attImpl.getValue("v")); // insert key and value of that tag into Hashtable
+ }
+ if (inNode || inWay) {
+ AttributesImpl attImpl = new AttributesImpl(attributes);
+ if (attImpl.getValue("k").equals("public_transport")) {
+ nodeWayPtValue.put(nodeWayId, attImpl.getValue("v"));
+ }
+ }
}
if (tempMembers!=null && qname.equals("member")) {
AttributesImpl attImpl = new AttributesImpl(attributes);
- RelationMember rm = new RelationMember(attImpl.getValue("ref"),attImpl.getValue("type"),attImpl.getValue("role"));
+ RelationMember rm = new RelationMember(attImpl.getValue("ref"), attImpl.getValue("type"), attImpl.getValue("role"), "", "", "unknown");
rm.setStatus("OSM server");
tempMembers.add(rm);
}
+ if (qname.equals("node")) {
+ inNode = true;
+ AttributesImpl attImpl = new AttributesImpl(attributes);
+ nodeWayId = attImpl.getValue("id");
+ nodes.put(attImpl.getValue("id"), attImpl.getValue("lat") + ";" + attImpl.getValue("lon"));
+ }
+ if (qname.equals("way")) {
+ inWay = true;
+ AttributesImpl attImpl = new AttributesImpl(attributes);
+ nodeWayId = attImpl.getValue("id");
+ }
+ if (qname.equals("nd") && inWay && ndcount == 0) {
+ ndcount++;
+ AttributesImpl attImpl = new AttributesImpl(attributes);
+ ways.put(nodeWayId, attImpl.getValue("ref"));
+ }
}
@Override public void endElement (String uri, String localName, String qName) throws SAXException {
@@ -68,6 +105,44 @@ public RouteParser(){
tempTag = null;
tempMembers = null;
}
+ if (qName.equals("way")) {
+ inWay = false;
+ ndcount = 0;
+ }
+ if (qName.equals("node")) {
+ inNode = false;
+ ndcount = 0;
+ }
+ }
+
+ @Override
+ public void endDocument() throws SAXException {
+ super.endDocument();
+ HashMap waysWithGeo = new HashMap<>();
+ for (HashMap.Entry way : ways.entrySet()) {
+ waysWithGeo.put(way.getKey(), nodes.get(way.getValue()));
+ }
+
+ for (LinkedHashSet hs : xmlMembers) {
+ for (RelationMember m : hs) {
+ String nodeId = nodes.get(m.getRef());
+ //System.out.println(String.format("Id: %s / nodeId: %s", m.getRef(), nodeId));
+ if (nodeId != null) {
+ m.setLat(nodeId.split(";")[0]);
+ m.setLon(nodeId.split(";")[1]);
+ } else {
+ String wayId = waysWithGeo.get(m.getRef());
+ //System.out.println(String.format("Id: %s / wayId: %s", m.getRef(), wayId));
+ if (wayId != null) {
+ m.setLat(wayId.split(";")[0]);
+ m.setLon(wayId.split(";")[1]);
+ }
+ }
+ if (nodeWayPtValue.containsKey(m.getRef())) {
+ m.setRefOsmPublicTransportType(nodeWayPtValue.get(m.getRef()));
+ }
+ }
+ }
}
public ArrayList getRelations(){