Skip to content

v0.2.47..v0.2.48 changeset Way.java

Garret Voltz edited this page Sep 27, 2019 · 1 revision
diff --git a/hoot-services/src/main/java/hoot/services/models/osm/Way.java b/hoot-services/src/main/java/hoot/services/models/osm/Way.java
index e039349..59777e6 100644
--- a/hoot-services/src/main/java/hoot/services/models/osm/Way.java
+++ b/hoot-services/src/main/java/hoot/services/models/osm/Way.java
@@ -298,26 +298,52 @@ public class Way extends Element {
                 multiLayerUniqueElementIds, addChildren);
         Document doc = parentXml.getOwnerDocument();
 
+        List<Long> nodeIds = getNodeIds();
+        Set<Long> elementIds = new HashSet<>();
+
+        // way nodes are output in sequence order; list should already be sorted by the query
+        for (long nodeId : nodeIds) {
+            org.w3c.dom.Element nodeElement = doc.createElement("nd");
+            nodeElement.setAttribute("ref", String.valueOf(nodeId));
+            element.appendChild(nodeElement);
+            elementIds.add(nodeId);
+        }
+
         if (addChildren) {
-            List<Long> nodeIds = getNodeIds();
-            Set<Long> elementIds = new HashSet<>();
-
-            // way nodes are output in sequence order; list should already be sorted by the query
-            for (long nodeId : nodeIds) {
-                org.w3c.dom.Element nodeElement = doc.createElement("nd");
-                nodeElement.setAttribute("ref", String.valueOf(nodeId));
-                element.appendChild(nodeElement);
-                elementIds.add(nodeId);
-            }
 
             List<Tuple> elementRecords = (List<Tuple>) Element.getElementRecordsWithUserInfo(getMapId(),
                     ElementType.Node, elementIds);
 
+            // It is too slow to do an XPathApi call for every single node to check if it
+            // already exists so its better to just get all nodes and store the ids in list
+            // and check against the list instead.
+            NodeList allNodesList;
+            try {
+                allNodesList = XPathAPI.selectNodeList(doc, "/osm/node/@id");
+            }
+            catch (TransformerException e) {
+                throw new RuntimeException("Error invoking XPathAPI!", e);
+            }
+
+            ArrayList<String> allNodeIds = new ArrayList<>();
+            for(int i = 0; i< allNodesList.getLength(); i++) {
+                allNodeIds.add(allNodesList.item(i).getNodeValue());
+            }
+
             for (Tuple elementRecord : elementRecords) {
-                Element nodeFullElement = ElementFactory.create(ElementType.Node, elementRecord, getMapId());
-                org.w3c.dom.Element nodeXml = nodeFullElement.toXml(parentXml, modifyingUserId,
-                        modifyingUserDisplayName, false, false);
-                parentXml.appendChild(nodeXml);
+                String nodeId = elementRecord.get(currentNodes).getId() + ""; // convert to string for cases of multiLayerUniqueElementIds
+
+                if (multiLayerUniqueElementIds) {
+                    nodeId = getMapId() + "_n_" + nodeId; // hoot custom id unique across map layers
+                }
+
+                // If the node element doesnt exist then add it
+                if(!allNodeIds.contains(nodeId)) {
+                    Element nodeFullElement = ElementFactory.create(ElementType.Node, elementRecord, getMapId());
+                    org.w3c.dom.Element nodeXml = nodeFullElement.toXml(parentXml, modifyingUserId,
+                            modifyingUserDisplayName, false, false);
+                    parentXml.appendChild(nodeXml);
+                }
             }
         }
 
Clone this wiki locally