/gwik-main/src/java/gwik/osm/OsmResponseParser.java

https://github.com/e-learning/gwik · Java · 152 lines · 128 code · 20 blank · 4 comment · 12 complexity · 68f5dabdc2e32277304bbd1686cbbd9e MD5 · raw file

  1. package gwik.osm;
  2. import org.apache.log4j.Logger;
  3. import org.w3c.dom.Document;
  4. import org.w3c.dom.Node;
  5. import org.w3c.dom.NodeList;
  6. import org.xml.sax.SAXException;
  7. import javax.xml.parsers.DocumentBuilderFactory;
  8. import javax.xml.parsers.ParserConfigurationException;
  9. import javax.xml.xpath.XPath;
  10. import javax.xml.xpath.XPathConstants;
  11. import javax.xml.xpath.XPathExpressionException;
  12. import javax.xml.xpath.XPathFactory;
  13. import java.io.IOException;
  14. import java.io.InputStream;
  15. import java.net.HttpURLConnection;
  16. import java.net.URL;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. /**
  20. * @author: Vladislav Dolbilov (darl@yandex-team.ru)
  21. * Date: 03.11.11 0:27
  22. */
  23. public class OsmResponseParser {
  24. private static final Logger log = Logger.getLogger(OsmResponseParser.class);
  25. public List<WikiObject> parse(String urlStr) {
  26. HttpURLConnection urlc = null;
  27. try {
  28. URL url = new URL(urlStr);
  29. urlc = (HttpURLConnection) url.openConnection();
  30. return parse(urlc.getInputStream());
  31. } catch (IOException e) {
  32. throw new RuntimeException(e);
  33. } finally {
  34. if (urlc != null) {
  35. urlc.disconnect();
  36. }
  37. }
  38. }
  39. protected List<WikiObject> parse(InputStream is) throws IOException {
  40. List<WikiObject> result = new ArrayList<WikiObject>();
  41. try {
  42. Document doc = parserXML(is);
  43. XPathFactory f = XPathFactory.newInstance();
  44. XPath xpath = f.newXPath();
  45. extractNodes(doc, xpath, result);
  46. extractWays(doc, xpath, result);
  47. extractRelations(doc, xpath, result);
  48. } catch (Exception e) {
  49. throw new RuntimeException(e);
  50. } finally {
  51. is.close();
  52. }
  53. return result;
  54. }
  55. private void extractRelations(Document doc, XPath xpath, List<WikiObject> result) throws XPathExpressionException {
  56. NodeList relations = (NodeList) xpath.evaluate("/osm/relation[tag/@k='wikipedia']", doc, XPathConstants.NODESET);
  57. for (int i = 0; i < relations.getLength(); ++i) {
  58. Node relation = relations.item(i);
  59. double lon = 0;
  60. double lat = 0;
  61. int count = 0;
  62. NodeList relationWays =
  63. (NodeList) xpath.evaluate("member[@type = 'way']/@ref", relation, XPathConstants.NODESET);
  64. log.debug("relation way count " + relationWays.getLength());
  65. for (int j = 0; j < relationWays.getLength(); ++j) {
  66. Node way = (Node) xpath.evaluate("/osm/way[@id = '" + relationWays.item(j).getTextContent() + "']", doc, XPathConstants.NODE);
  67. if (way != null) {
  68. NodeList wayNodes = (NodeList) xpath.evaluate("nd/@ref", way, XPathConstants.NODESET);
  69. log.debug("way node count " + wayNodes.getLength());
  70. for (int h = 0; h < wayNodes.getLength(); ++h) {
  71. Node node = (Node) xpath.evaluate("/osm/node[@id = '" + wayNodes.item(h).getTextContent() + "']", doc, XPathConstants.NODE);
  72. lon += Double.parseDouble(xpath.evaluate("@lon", node));
  73. lat += Double.parseDouble(xpath.evaluate("@lat", node));
  74. count++;
  75. }
  76. }
  77. }
  78. NodeList relationNodes =
  79. (NodeList) xpath.evaluate("member[@type = 'node']/@ref", relation, XPathConstants.NODESET);
  80. log.debug("relation node count " + relationNodes.getLength());
  81. for (int j = 0; j < relationNodes.getLength(); ++j) {
  82. Node node = (Node) xpath.evaluate("/osm/node[@id = '" + relationNodes.item(j).getTextContent() + "']", doc, XPathConstants.NODE);
  83. lon += Double.parseDouble(xpath.evaluate("@lon", node));
  84. lat += Double.parseDouble(xpath.evaluate("@lat", node));
  85. count++;
  86. }
  87. if (count > 0) {
  88. result.add(new WikiObject(
  89. xpath.evaluate("tag[@k='wikipedia']/@v", relation),
  90. lon / count,
  91. lat / count
  92. ));
  93. }
  94. }
  95. }
  96. private void extractWays(Document doc, XPath xpath, List<WikiObject> result) throws XPathExpressionException {
  97. NodeList ways = (NodeList) xpath.evaluate("/osm/way[tag/@k='wikipedia']", doc, XPathConstants.NODESET);
  98. for (int i = 0; i < ways.getLength(); ++i) {
  99. Node way = ways.item(i);
  100. double lon = 0;
  101. double lat = 0;
  102. int count = 0;
  103. NodeList wayNodes = (NodeList) xpath.evaluate("nd/@ref", way, XPathConstants.NODESET);
  104. log.debug("way node count " + wayNodes.getLength());
  105. for (int j = 0; j < wayNodes.getLength(); ++j) {
  106. Node node = (Node) xpath.evaluate("/osm/node[@id = '" + wayNodes.item(j).getTextContent() + "']", doc, XPathConstants.NODE);
  107. lon += Double.parseDouble(xpath.evaluate("@lon", node));
  108. lat += Double.parseDouble(xpath.evaluate("@lat", node));
  109. count++;
  110. }
  111. result.add(new WikiObject(
  112. xpath.evaluate("tag[@k='wikipedia']/@v", way),
  113. lon / count,
  114. lat / count
  115. ));
  116. }
  117. }
  118. private void extractNodes(Document doc, XPath xpath, List<WikiObject> result) throws XPathExpressionException {
  119. NodeList nodes = (NodeList) xpath.evaluate("/osm/node[tag/@k='wikipedia']", doc, XPathConstants.NODESET);
  120. for (int i = 0; i < nodes.getLength(); ++i) {
  121. Node node = nodes.item(i);
  122. result.add(new WikiObject(
  123. xpath.evaluate("tag[@k='wikipedia']/@v", node),
  124. Double.parseDouble(xpath.evaluate("@lon", node)),
  125. Double.parseDouble(xpath.evaluate("@lat", node))
  126. ));
  127. }
  128. }
  129. private Document parserXML(InputStream is) throws SAXException, IOException, ParserConfigurationException {
  130. return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
  131. }
  132. }